2013-10-15 15 views
13

Qualcuno può spiegare perché questo codice produce l'output sottostante?I riferimenti booleani sono nulli

@Test 
public void testBooleanArray() { 
    Boolean[] ab = new Boolean[]{a, b}; 

    a = new Boolean(true); 
    b = new Boolean(false); 

    for(Boolean x : ab) { 
     System.out.println(x); 
    } 
} 

risultati:

null 
null 

Qualora la matrice ab non contiene puntatori ad oggetto un e b oggetto, e quindi l'uscita:

true 
false 
+3

Ora la domanda del trucco è come mai è possibile assegnare le variabili senza che Java si lamenti di non esistere: p. P.S: nota l'annotazione @Test. –

+3

Ho lasciato la dichiarazione per brevità - niente di interessante da vedere lì! – StuPointerException

+1

Ah peccato. Pensavo che ci fosse un po 'di "magia" indotta dall'ambiente di test. Ovviamente non è il caso, ma ho visto cose strane :) –

risposta

21
a = new Boolean(true); 
b = new Boolean(false); 

Ciò non cambia gli oggetti a cui puntava eb (gli elementi nell'array). Li indirizza agli oggetti new.

Non è modfying matrice

Per chiarire:

Boolean a = new Boolean(true); 
Boolean b = new Boolean(false); 
Boolean c = a; 
Boolean d = b; 
a = new Boolean(false); 
b = new Boolean(true); 

ced saranno comunque vero/falso rispettivamente. Questa è la stessa cosa che sta accadendo con l'array, ad eccezione del fatto che il riferimento dell'array non è chiamato allo stesso modo.

+3

Buzz kill/tempo di formulazione corretto. Il codice sopra cambia l'oggetto a cui 'a' e' b' puntano. Tuttavia, non modifica gli oggetti a cui puntano i riferimenti all'elemento dell'array copiati da 'a' e' b' ('null'). –

+0

@SotiriosDelimanolis riformulato per chiarimenti – Cruncher

+3

@SotiriosDelimanolis Ci stavo pensando un po ', ed era davvero solo l'ambiguità linguistica (ancora meglio chiarita che no). Se faccio 'a.change()', potrei dire: 'Ho cambiato l'oggetto a cui punta a'. Se faccio 'a = new Object();', potrei dire: 'Ho cambiato l'oggetto a cui punta a'. È solo che si sta parlando del riferimento e l'altro dell'oggetto. – Cruncher

8

Devi inizializzare i tuoi booleani prima di assegnarli.

Boolean[] ab = new Boolean[]{a, b}; 

a = new Boolean(true); 
b = new Boolean(false); 

a

a = new Boolean(true); 
b = new Boolean(false); 

Boolean[] ab = new Boolean[]{a, b}; 

Questo è prima con gli oggetti, si copia il riferimento all'oggetto, e con la nuova dichiarazione, si crea un nuovo oggetto, il primo a, b erano nulla quando l'assegnazione.

3

... Che è assolutamente normale. Si stanno inizializzando i valori ma, in modo sequenziale, a e sono ancora null prima che il processo passi all'assegnazione delle variabili. Non sono le variabili che vengono posizionate ma i loro valori o riferimenti come elementi in un array.

@Test 
public void testBooleanArray() { 
    /* We have a Boolean array, Boolean being able to hold a true, false but 
    also a null as an object */ 
    Boolean[] ab = new Boolean[]{a, b}; /* We initialize the array with the variables 
    here but ... */ 

    a = new Boolean(true); // ... the instances are only set at this stage 
    b = new Boolean(false); /* Plus, even if Boolean is immutable, the use of new 
    will actually create new objects */ 

    for(Boolean x : ab) { 
     System.out.println(x); 
    } 
} 
6

Il codice srotolato:

Boolean a = null; 
Boolean b = null; 
Boolean[] ab = new Boolean[2]; 
ab[0] = a; 
ab[1] = b; 

a = new Boolean(true); 
b = new Boolean(false); 

Il momento il contenuto delle variabili di nome A e B era copiato alla matrice, è stato impostato su null. C'è un'importante differenza per copia per valore e copia per riferimento.

Come nota a margine: si consiglia di utilizzare Boolean.TRUE al posto o almeno Boolean.valueOf (true), per evitare la creazione di oggetti non necessari. Non ci sono molte opzioni per un valore booleano e Boolean è immutable.

+0

+1 Mi piace. I salti hanno superato un po 'di zucchero sintattico e mostrano come non è diverso dall'esempio nella mia risposta. – Cruncher

4

Penso che sia utile visualizzare gli elementi dell'array come puntatori.

Per prima cosa creiamo due puntatori, a e b, entrambi puntati su null.

Boolean a = null, b = null; 

Pointers a and b point to null

Successivamente, creare più di due puntatori, ab[0] e ab[1], e puntare allo stesso posto come a e b. Cioè, null.

Boolean[] ab = new Boolean[]{a, b}; 

All four pointers point to null

Poi, creiamo nuove booleane true e false oggetti (con le new Boolean(true) e new Boolean(false) parti delle dichiarazioni).

Two new Booleans have been created

Infine, lasciamo a e b punto a loro.

a = new Boolean(true); 
b = new Boolean(false); 

a and b point to the new Booleans

Quando si guarda in questo modo, penso che sia più chiaro il motivo per cambiare a e b non ha alcun effetto sulla matrice.

+0

Bella illustrazione.Potresti entrare in allenamento o insegnare :) –