2009-02-26 15 views
14

Il codice seguente non fa ciò che mi aspetto. Ogni stringa è null dopo l'esecuzione di questo codice.Informazioni su ogni loop in Java

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

Il codice seguente fa quello che mi aspetto. Ogni stringa in currentState è ora "_"

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

Qualcuno può spiegare perché il primo caso non funziona?

+0

Presumibilmente si vuol dire questo, invece: String [] currentState = new String [answer.length()]; –

risposta

31

In base alla progettazione, per ogni variabile 'x' (in questo caso) non è previsto l'assegnazione. Sono sorpreso che compili anche bene.

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

Il seguente codice mostra forse quello che stai facendo in effetti. Nota che questo non è il modo in cui funzionano le enumerazioni ma esemplifica il motivo per cui non puoi assegnare 'x'. È una copia dell'elemento nella posizione 'i'. (Edit: notare che l'elemento è un tipo di riferimento, in quanto tale è una copia di tale rinvio, l'assegnazione a tale copia non aggiorna la stessa memoria cioè l'elemento in posizione 'i')

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

oh, quindi quando eseguo (String x: currentState), crea una NUOVA stringa, xe copia il VALUE della stringa in currentState? –

+0

non importa, vedo, sto solo cambiando il riferimento –

+1

"Sono sorpreso che compili anche bene". Certo che compila bene. Se non vuoi un incarico basterà x final. – cadrian

4

Poiché x è un riferimento (o una variabile di tipo di riferimento). Tutto il primo pezzo di codice fa re-puntare il riferimento su un nuovo valore. Per esempio

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

Il fatto che si sono ri-assegnare il riferimento y a "Bob" non influenza quello che il riferimento x è stato assegnato a.

+0

Nel codice di esempio x * non è * un riferimento. È una variabile il cui valore è solo un int. Confronta questo con il codice originale, in cui il valore di x * è * un riferimento perché String è un tipo di riferimento. –

+0

Sì, certo. Stavo solo cercando di renderlo semplice. Pensavo che entrare nella semantica di "variabile di tipo di riferimento" e "variabile di tipo primitivo" non fosse probabilmente necessario. A tutti gli effetti, penso che x possa essere pensato come riferimento ad un certo valore. Tipo modificato in Stringa –

+0

Stai meglio se hai fatto 'y = "Bob";' ... rende più ovvio che quando x "punta a y" non è un puntatore a un puntatore (qualcosa su cui alcune persone rimangono bloccate quando iniziano con Java) – TofuBeer

9

Codice originale:

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

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

Riscritto codice:

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

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

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

Come faccio a scrivere il codice:

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

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

codice riscritto con l'errore:

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

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

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

Rendere le variabili evidenti quando si fanno cose del genere (è un errore principiante comune). Prova a rendere definitive tutte le tue variabili (istanza, classe, argomenti, eccezioni in catch ecc.) - rendili non definitive se devi davvero cambiarle. Dovresti scoprire che il 90% -95% delle tue variabili è definitivo (i principianti finiranno con il 20% -50% quando inizieranno a farlo).

-1

È possibile convertire l'array a una lista e poi iterare in questo modo:

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

Object x [] = {1, "ram", 30000f, 35, "conto"}; per (oggetto i: x) System.out.println (i); per ciascuna viene utilizzato per l'accesso sequenziale

-1

Il per ogni loop significato per questo:

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

in modo da considerare al di sopra si può fare questo:

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