creando variables finales dentro de un bucle

esto está permitido en java:

for(int i=0;i<5;i++){ final int myFinalVariable = i; } 

La palabra clave de mi pregunta es final . ¿Está permitido hacer una variable final que cambie con cada ejecución del ciclo? Me lo estaba preguntando porque final dice que no se puede cambiar el valor de la variable (llamando únicamente a myFinalVariable = i ), pero estoy redefiniendo la variable completa con final int .

¿Son dos variables completamente diferentes con el mismo nombre, con la variable de la ejecución anterior del bucle que ya se dirige hacia el recolector de basura?

Sí, está permitido. La palabra clave final significa que no puede cambiar el valor de la variable dentro de su scope . Para su ejemplo de bucle, puede pensar en la variable que sale del scope en la parte inferior del bucle, y luego volver al scope con un nuevo valor en la parte superior del bucle. Asignar a la variable dentro del bucle no funcionará.

Tienes razón, para cada iteración en el ciclo, estás creando una nueva variable. Las variables comparten el mismo nombre, pero eso está bien porque no están en el mismo scope. El siguiente ejemplo no funcionaría:

 final int myFinalVariable = 0; for(int i=0;i<5;i++){ myFinalVariable = i; } 

Una variable es solo una ubicación en la stack. Intenta mantener tus variables con un scope lo más pequeño posible e intenta que sean definitivas. Sin embargo, el scope y el final son solo cosas del código fuente … desde el punto de vista de generación de código / VM realmente no importan en absoluto.

En su ejemplo específico, al usar “int” no se crea basura. Sin embargo, si se crean objetos, en ambos casos la cantidad de basura y cuándo la basura sería elegible para la limpieza sería idéntica.

Toma el siguiente código:

 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; } } } 

El comstackdor produce un bytecode idéntico para cada método:

 public class X extends java.lang.Object{ public X(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()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 } 

Al agregar otro método que declara la variable fuera del ciclo, se obtiene un bytecode levemente diferente debido al orden en que se declaran las variables). Tenga en cuenta que esta versión de la variable no se puede hacer definitiva. Esta última versión no es la mejor (la variable final dentro del ciclo es la mejor si puede hacerlo):

 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 } 

Como respondió, sí, de hecho puede marcar las variables en un bucle como ‘final’. Aquí está el efecto de hacerlo (Java 7, Eclipse Indigo, Mac OS X Lion).

 for ( int i = 0; i < 5; i++ ) { // With 'final' you cannot assign a new value. final int myFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration. myFinalVariable = 7; // Compiler error: The final local variable myFinalVariable cannot be assigned. // Without 'final' you can assign a new value. int myNotFinalVariable = i; // Gets 0, 1, 2, 3, or 4 on each iteration. myNotFinalVariable = 7; // Compiler is OK with re-assignment of variable's value. } 

La variable declarada dentro del ciclo tiene el scope únicamente hasta la ejecución única del ciclo.

Declarar la variable como final dentro del bucle no hace ninguna diferencia para la variable en el lado del bucle, pero si declaramos la variable fuera del bucle con modificador final, entonces el valor asignado al tipo primitivo u Objeto asignado a la variable de referencia no se puede cambiar.

En el ejemplo siguiente, no hay problemas con los dos primeros bucles, ambos bucles dan el mismo resultado, pero el tercer bucle da un error de tiempo de comstackción.

prueba de clase pública {

 public static void main(String[] args) { for (int i = 0; i < 5; i++) { final int j= i; System.out.println(j); } for (int i = 0; i < 5; i++) { int j= i; System.out.println(j); } final int j; for (int i = 0; i < 5; i++) { j= i; System.out.println(j); } } 

}

Por favor corrígeme si estoy equivocado.