2009-02-26 15 views
14

El siguiente código no hace lo que esperaba. Cada cadena es nula después de que se ejecuta este código.Entendimiento para cada ciclo en Java

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

El código siguiente hace lo que espero. Cada cadena en currentState ahora es "_"

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

¿Alguien puede explicar por qué el primer caso no funciona?

+0

Es de suponer que significa esto en su lugar: Cadena [] currentState = new String [answer.length()]; –

Respuesta

31

Por diseño, para cada variable 'x' (en este caso) no se debe asignar. Me sorprende que incluso compila bien.

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

El siguiente código puede mostrar lo que estás haciendo en realidad. Tenga en cuenta que esta no es la forma en que funcionan las enumeraciones, sino que ejemplifica por qué no puede asignar 'x'. Es una copia del elemento en la ubicación 'i'. (Edit: en cuenta que el elemento es un tipo de referencia, como tal, es una copia de esa referencia, la asignación a esa copia no actualiza la misma posición de memoria, es decir el elemento en la posición 'i')

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

oh, cuando lo hago (String x: currentState), crea una NUEVA cadena, x, y copia el VALOR de la cadena en currentState? –

+0

no importa, ya veo, estoy cambiando la referencia –

+1

"Me sorprende que incluso compila bien". Por supuesto, compila bien. Si no quiere la asignación solo haga x final. – cadrian

4

Debido x es una referencia (o una variable del tipo de referencia). Todo lo que hace la primera parte del código es volver a señalar la referencia en un nuevo valor. Por ejemplo

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

El hecho de que se vuelven a asignar la referencia y a "Bob" no afecta a lo que la referencia x fue asignado a.

+0

En su código de ejemplo x * no es * una referencia. Es una variable cuyo valor es solo un int. Compare esto con el código original, donde el valor de x * es * una referencia porque String es un tipo de referencia. –

+0

Sí, por supuesto. Solo estaba tratando de mantenerlo simple. Pensé que entrar a la semántica de "variable de tipo de referencia" y "variable de tipo primitivo" probablemente era innecesaria. A todos los efectos, creo que se puede pensar en x como una referencia a algún valor. Se cambió el tipo a Cadena –

+0

Sería mejor si lo hiciera 'y = "Bob";' ... hace que sea más obvio que cuando x "apunta a y" no es un puntero a un puntero (algo a lo que algunas personas se atascan cuando están comenzando con Java) – TofuBeer

9

Código original:

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

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

Refundido código:

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

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

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

Cómo me gustaría escribir el código:

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

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

código reescrito con el error:

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

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

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

Hacer que las variables destaquen al hacer cosas como esta (es un error común de principiante). Intenta hacer que todas tus variables sean definitivas (instancia, clase, argumentos, excepciones en catch, etc ...), solo haz que no sean definitivas si realmente tienes que cambiarlas. Deberías encontrar que el 90% -95% de tus variables son definitivas (los principiantes terminarán con un 20% -50% cuando comiencen a hacer esto).

-1

Puede convertir su matriz a una lista y luego repetir la siguiente manera:

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

objeto X [] = {1, "RAM", 30000f, de 35 años, "cuenta"}; para (Objeto i: x) System.out.println (i); para cada uno se utiliza para el acceso secuencial

-1

El para cada bucle destinado para esto:

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

por lo consideran por encima de usted puede hacer esto:

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