2009-02-26 10 views
14

Le code ci-dessous ne fait pas ce que j'attends. Chaque chaîne est nulle après l'exécution de ce code.Comprendre pour chaque boucle en Java

String[] currentState = new String[answer.length()]; 
for(String x : currentState) 
{ 
    x = "_"; 
} 

Le code ci-dessous fait ce que j'attends. Chaque chaîne dans currentState est maintenant "_"

String[] currentState = new String[answer.length()]; 
for (int i = 0; i < currentState.length; i++) { 
    currentState[i] = "_"; 
} 

Quelqu'un peut-il expliquer pourquoi le premier cas ne fonctionne pas?

+0

On peut supposer que vous voulez dire ceci: cordes [] currentState = new Chaîne [answer.length()]; –

Répondre

31

Par conception, pour chaque variable 'x' (dans ce cas) n'est pas destiné à être affecté. Je suis surpris qu'il compile même bien.

String[] currentState = new String[answer.length()]; 
for (String x : currentState) { 
    x = "_"; // x is not a reference to some element of currentState 
} 

Le code suivant peut indiquer ce que vous êtes en train de faire. Notez que ce n'est pas comme cela que les énumérations fonctionnent mais cela illustre pourquoi vous ne pouvez pas assigner 'x'. C'est une copie de l'élément à l'emplacement 'i'. (Edit: Notez que l'élément est un type de référence, en tant que tel, il est une copie de cette référence, l'affectation à cette copie ne met pas à jour le même emplacement mémoire à savoir l'élément à l'emplacement « i »)

String[] currentState = new String[answer.length()]; 
for (int i = 0; i < answer.length(); i++) { 
    String x = currentState[i]; 
    x = "_"; 
} 
+1

oh, donc quand je le fais (String x: currentState), il crée une nouvelle chaîne, x, et copie la valeur de la chaîne dans currentState? –

+0

ça ne va pas, je vois, je change juste la référence –

+1

"Je suis surpris qu'il se compile même bien". Bien sûr, il compile bien. Si vous ne voulez pas d'affectation, faites juste x final. – cadrian

4

Parce que x est une référence (ou une variable de type de référence). Tout le premier morceau de code est re-pointer la référence à une nouvelle valeur. Par exemple

String y = "Jim"; 
String x = y; 
y = "Bob"; 
System.out.println(x); //prints Jim 
System.out.println(y); //prints Bob 

Le fait que vous réattribuant la référence y à « Bob » ne modifie pas ce que la référence x a été affecté.

+0

Dans votre exemple de code, x * n'est pas * une référence. C'est une variable dont la valeur est juste un int. Comparez cela avec le code original, où la valeur de x * est * une référence car String est un type de référence. –

+0

Oui, bien sûr. J'essayais juste de garder les choses simples. Je pensais qu'entrer dans la sémantique de "variable de type de référence" et "variable de type primitif" était probablement inutile. À toutes fins pratiques, je pense que x peut être considéré comme une référence à une certaine valeur. Type changé en String –

+0

Mieux vaut si vous avez fait 'y = "Bob";' ... rend plus évident que lorsque x "pointe sur y" ce n'est pas un pointeur vers un pointeur (quelque chose que certaines personnes bloquent quand elles commencent avec Java) – TofuBeer

9

Code d'origine:

String currentState = new String[answer.length()]; 

for(String x : currentState) 
{ 
    x = "_"; 
} 

Code Réécriture:

String currentState = new String[answer.length()]; 

for(int i = 0; i < currentState.length; i++) 
{ 
    String x; 

    x = currentState[i]; 
    x = "_"; 
} 

Comment j'écrire le code:

String currentState = new String[answer.length()]; 

for(final String x : currentState) 
{ 
    x = "_"; // compiler error 
} 

Code Réécriture avec l'erreur:

String currentState = new String[answer.length()]; 

for(int i = 0; i < currentState.length; i++) 
{ 
    final String x; 

    x = currentState[i]; 
    x = "_"; // compiler error 
} 

Rendre les variables finales en surbrillance lorsque vous faites des choses comme ça (c'est une erreur débutant commun). Essayez de rendre toutes vos variables finales (instance, classe, arguments, exceptions dans catch, etc ...) - faites-les seulement non finales si vous devez vraiment les changer. Vous devriez trouver que 90% -95% de vos variables sont finales (les débutants finiront par 20% -50% quand ils commencent à faire cela).

-1

Vous pouvez convertir votre tableau à une liste, puis itérer comme ceci:

String[] currentState = new String[answer.length()]; 
List<String> list = Arrays.asList(currentState); 
for(String string : list) { 
    x = "_";  
} 
-1

Object x [] = {1, "bélier", 30000f, 35, "compte"}; pour (Objet i: x) System.out.println (i); pour chacun est utilisé pour l'accès séquentiel

-1

La pour chaque boucle destinée à ceci:

List suits = ...; 
List ranks = ...; 
List sortedDeck = new ArrayList(); 
for (Suit suit : suits){ 
    for (Rank rank : ranks) 
     sortedDeck.add(new Card(suit, rank)); 
} 

Regarde donc ci-dessus, vous pouvez le faire:

String[] currentState = new String[answer.length()]; 
List<String> buffList = new ArrayList<>(); 
for (String x : currentState){ 
     x = "_"; 
     buffList.add(x); 
     // buffList.add(x = "_"); will be work too 
} 
currentState = buffList.toArray(currentState); 
Questions connexes