48 votes

création de variables finales à l'intérieur d'une boucle

est-ce possible en java:

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

Le mot-clé de ma question est - final. Est-il permis de faire une dernière variable qui change à chaque exécution de la boucle? Je me demandais ce que final dit que vous ne pouvez pas modifier la valeur de la variable (en appelant seulement myFinalVariable = i), mais je suis la redéfinition de l'ensemble de la variable final int.

Ils sont deux totalement différents variables avec le même nom, avec la variable à partir de l'exécution précédente de la boucle déjà tête en bas de la route pour le garbage collector?

83voto

Greg Hewgill Points 356191

Oui, c'est permis. Le mot clé final signifie que vous ne pouvez pas modifier la valeur de la variable dans sa portée . Pour votre exemple de boucle, vous pouvez penser à la variable qui sort de la portée en bas de la boucle, puis qui revient dans la portée avec une nouvelle valeur en haut de la boucle. L'affectation à la variable dans la boucle ne fonctionnera pas.

12voto

tehvan Points 3949

Vous avez raison, pour chaque itération de la boucle, vous créez une nouvelle variable. Les variables partagent le même nom, mais c'est très bien car elles ne sont pas dans la même portée. L'exemple suivant ne fonctionnerait pas :

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

9voto

TofuBeer Points 32441

Une variable est juste un emplacement sur la pile. Essayez de garder vos variables petit possible, et essayer de leur faire finale. Toutefois, la portée et la finale sont juste le code source des choses... d'une génération de code/VM point de vue qu'ils n'ont pas vraiment d'importance.

Dans votre exemple, à l'aide de "int" aucun déchet n'est créé. Toutefois, si c'étaient des objets en cours de création alors pour les deux cas, la quantité de déchets et lorsque les déchets serait admissible pour le nettoyage serait identique.

Prenez le code suivant:

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

Le compilateur produit identique bytecode pour chaque méthode:

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

}

L'ajout d'une autre méthode qui déclare la variable en dehors de la boucle de vous donner légèrement différentes bytecode en raison de l'ordre dans lequel les variables sont déclarées). Notez que cette version de la variable ne peut pas être le dernier. Cette dernière version n'est pas la meilleure façon (la dernière variable à l'intérieur de la boucle est le meilleur si vous pouvez le faire):

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

}

2voto

Setu Poddar Points 19

Variable déclarée à l'intérieur de la boucle de la portée que jusqu'à la seule exécution de la boucle.

Déclarer la variable final à l'intérieur de la boucle, le pas de différence pour la variable dans le côté de la boucle, mais si nous déclarons la variable en dehors de la boucle avec le modificateur final alors que la valeur attribuée au type primitif ou d'un Objet affecté à la variable de référence ne peut pas être modifié .

Dans l'exemple ci-dessous il n'y a pas de problème avec les deux premières boucles à la fois les boucles de donner le même résultat, mais la troisième boucle donne une Erreur de compilation.

public class test {

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

}

S'il vous plaît ne me corriger si je me trompe.

2voto

Basil Bourque Points 8938

Comme répondu, oui, vous pouvez en effet marquer les variables d'une boucle comme «finales». En voici l'effet (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.

}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X