Zmienna jest tylko miejsce na stosie. Staraj się przechowywać zmienne z możliwie najmniejszym zakresem i staraj się, aby były ostateczne. Jednak zakres i finał są po prostu kwestią kodu źródłowego ... z punktu widzenia generowania kodu/VM naprawdę nie mają znaczenia.
W twoim konkretnym przykładzie, używając "int", nie jest tworzone żadne śmieci. Jednak jeśli byłyby tworzone obiekty, to w obu przypadkach ilość śmieci i kiedy odpadki byłyby kwalifikujące się do czyszczenia, byłyby identyczne.
Weźmy następujący kod:
public class X
{
public static void main(final String[] argv)
{
foo();
bar();
}
private static void foo()
{
for(int i=0;i<5;i++)
{
final int myFinalVariable = i;
}
}
private static void bar()
{
for(int i=0;i<5;i++)
{
int myFinalVariable = i;
}
}
}
Kompilator wywołuje identyczną kodu bajtowego dla każdej metody:
public class X extends java.lang.Object{
public X();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: invokestatic #2; //Method foo:()V
3: invokestatic #3; //Method bar:()V
6: return
private static void foo();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
private static void bar();
Code:
0: iconst_0
1: istore_0
2: iload_0
3: iconst_5
4: if_icmpge 15
7: iload_0
8: istore_1
9: iinc 0, 1
12: goto 2
15: return
}
dodanie innego sposobu, który deklaruje zmienną poza pętlą daje nieco innego kodu bajtowego ze względu na kolejność deklarowania zmiennych). Zauważ, że tej wersji nie można ustawić jako ostatecznej. Ta ostatnia wersja nie jest najlepszym sposobem (ostateczna zmiennej wewnątrz pętli jest najlepszy, jeśli można to zrobić):
private static void car()
{
int myFinalVariable;
for(int i=0;i<5;i++)
{
myFinalVariable = i;
}
}
private static void car();
Code:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_5
4: if_icmpge 15
7: iload_1
8: istore_0
9: iinc 1, 1
12: goto 2
15: return
}