2013-10-15 17 views
13

Czy ktoś może wyjaśnić, dlaczego ten kod powoduje wynik poniżej?Odwołania logiczne mają wartość null

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

Wynik:

null 
null 

Jeżeli tablica ab nie posiada wskaźniki sprzeciwić się i obiektu B, a zatem wyjście:

true 
false 
+3

Teraz podchwytliwe pytanie brzmi: w jaki sposób możesz przypisać zmienne bez narzekania Java, które nie istnieją: p. P.S: Zwróć uwagę na adnotację @Test. –

+3

Zostawiłem deklarację dla zwięzłości - nic ciekawego do zobaczenia! – StuPointerException

+1

Ah wstyd. Myślałem, że w środowisku testowym pojawiła się jakaś "magia". Oczywiście nie w tym przypadku, ale widziałem dziwniejsze rzeczy :) –

Odpowiedz

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

To nie zmienia obiekty, na które wskazywali aib (elementy w tablicy). Wskazuje je na obiekty new.

Nie modfying tablicy

Dla ilustracji

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

cid nadal prawda/fałsz odpowiednio. Jest to to samo, co dzieje się z tablicą, z tym wyjątkiem, że odwołanie do tablicy nie ma takiej samej nazwy.

+3

Zabij Buzza/poprawne sformułowanie. Powyższy kod zmienia obiekt, na który wskazują 'a' i' b'. Nie zmienia jednak obiektów, do których odwołują się odwołania do elementu tablicy skopiowane z "a" i "b" ("null"). –

+0

@SotiriosDelimanolis przeformułowane na wyjaśnienia – Cruncher

+3

@SotiriosDelimanolis Myślałem o tym trochę, i to była naprawdę tylko wieloznaczność językowa (jeszcze lepiej wyjaśnione niż nie). Jeśli zrobię 'a.change()', mogę powiedzieć: 'Zmieniłem obiekt, który wskazuje na'. Jeśli zrobię 'a = new Object() ;, mogę powiedzieć:' Zmieniłem obiekt, który wskazuje na '. Chodzi o to, że mówi się o referencji, a drugi o obiekcie. – Cruncher

8

Musisz zainicjować swoje booleany przed ich przypisaniem.

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

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

do

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

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

to wcześniej z obiektów, kopiowania odniesienie do obiektu, a także z nowego rachunku, należy utworzyć nowy obiekt, pierwszy A, B była zerowa podczas przypisywania.

3

... Co jest absolutnie normalne. Inicjujesz wartości, ale kolejno, a i b są jeszcze przed procesem zaokrągleniem do przypisania zmiennych. Nie są to zmienne, które są umieszczane, ale ich wartości lub odniesienia jako elementy w tablicy.

@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

Kod rozwinął:

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

Moment zawartość zmiennych o nazwie A i B był kopiowane do tablicy, to było ustawione na null. Istnieje ważna różnica do kopii według wartości i kopiowania przez odniesienie.

Na marginesie: zaleca się użycie wartości Boolean.TRUE zamiast lub Boolean.valueOf (true), aby uniknąć niepotrzebnego tworzenia obiektów. Nie ma zbyt wielu opcji wartości boolowskiej, a wartość logiczna to niezmienna.

+0

+1 Podoba mi się to. Skips przekazał trochę cukru syntaktycznego i pokazuje, że nie różni się od przykładu w mojej odpowiedzi. – Cruncher

4

Myślę, że pomocne jest zwizualizowanie elementów tablicy jako wskaźników.

Najpierw tworzymy dwa wskaźniki: a i b, oba wskazują na zero.

Boolean a = null, b = null; 

Pointers a and b point to null

Następnie tworzymy kolejne dwa wskaźniki, ab[0] i ab[1], i wskazać je w tym samym miejscu co a i b. To znaczy, null.

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

All four pointers point to null

Następnie tworzymy nowe logicznych true i false obiektów (z new Boolean(true) i new Boolean(false) części sprawozdania).

Two new Booleans have been created

Wreszcie, niech a i b punkt do nich.

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

a and b point to the new Booleans

Jeśli spojrzeć na to w ten sposób, myślę, że to bardziej jasne, dlaczego zmienia a i b nie ma wpływu na tablicy.

+0

Ładna ilustracja.Możesz wziąć udział w szkoleniu lub nauczyć :) –

Powiązane problemy