2013-10-15 15 views
13

Bất cứ ai có thể giải thích tại sao mã này dẫn đến kết quả dưới đây?Tham chiếu Boolean là 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); 
    } 
} 

Kết quả:

null 
null 

nên mảng ab không giữ con trỏ đến một đối tượng và đối tượng b, và do đó đầu ra:

true 
false 
+3

Bây giờ câu hỏi mẹo là làm thế nào đến bạn có thể gán các biến mà không cần Java phàn nàn rằng chúng không tồn tại: p. P.S: Chú ý chú thích @Test. –

+3

Tôi để lại tuyên bố cho ngắn gọn - không có gì thú vị để xem ở đó! – StuPointerException

+1

Ah xấu hổ. Tôi nghĩ rằng có một số "ma thuật" gây ra bởi môi trường thử nghiệm. Rõ ràng không phải là trường hợp nhưng nhìn thấy những điều xa lạ :) –

Trả lời

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

này không thay đổi các đối tượng a và b trỏ đến (các phần tử trong mảng). Nó trỏ chúng đến các đối tượng new.

Nó không phải là modfying mảng

Để minh họa:

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

c và d vẫn sẽ đúng/sai tương ứng. Đây là điều tương tự đang xảy ra với mảng, ngoại trừ tham chiếu mảng của bạn không được đặt tên theo cùng một cách.

+3

Buzz giết/đúng thời gian từ ngữ. Đoạn mã trên không thay đổi đối tượng mà 'a' và' b' trỏ tới. Tuy nhiên, nó không thay đổi các đối tượng mà tham chiếu phần tử mảng được sao chép từ 'a' và' b' ('null') đang trỏ đến. –

+0

@SotiriosDelimanolis được viết lại để làm rõ – Cruncher

+3

@SotiriosDelimanolis Đã suy nghĩ về nó một chút, và nó thực sự chỉ là sự mơ hồ về ngôn ngữ (vẫn còn làm rõ hơn là không). Nếu tôi làm 'a.change()', tôi có thể nói: 'Tôi đã thay đổi đối tượng thành điểm '. Nếu tôi làm 'a = new Object();', tôi có thể nói: 'Tôi đã thay đổi đối tượng thành điểm '. Chỉ là người ta đang nói về tham chiếu, và đối tượng kia. – Cruncher

8

Bạn phải khởi tạo booleans của mình trước khi gán chúng.

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

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

để

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

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

Đây là trước khi có đối tượng, bạn sao chép các tài liệu tham khảo cho các đối tượng, và với tuyên bố mới, bạn tạo một đối tượng mới, là người đầu tiên a, b là null khi gán.

3

... Điều này hoàn toàn bình thường. Bạn đang khởi tạo các giá trị nhưng, theo tuần tự, ab vẫn là null trước khi quá trình chuyển thành vòng để gán biến. Nó không phải là các biến đang được đặt nhưng giá trị hoặc tham chiếu của chúng như là các phần tử trong một mảng.

@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

Mã của bạn trải ra:

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

Khoảnh khắc nội dung của các biến có tên là a và b là sao chép để mảng, nó được thiết lập để null. Có một sự khác biệt quan trọng đối với sao chép theo giá trịsao chép theo tham chiếu.

Lưu ý phụ: nên sử dụng Boolean.TRUE thay vì hoặc ít nhất là Boolean.valueOf (true), để tránh tạo đối tượng không cần thiết. Không có nhiều tùy chọn cho giá trị boolean và Boolean là không thay đổi.

+0

+1 Tôi thích điều này. Bỏ qua thông qua một số cú pháp đường, và cho thấy nó không khác với ví dụ trong câu trả lời của tôi. – Cruncher

4

Tôi nghĩ sẽ hữu ích khi trực quan hóa các phần tử mảng làm con trỏ.

Trước tiên, chúng tôi tạo hai con trỏ, ab, cả hai đều trỏ tới giá trị rỗng.

Boolean a = null, b = null; 

Pointers a and b point to null

Tiếp theo, chúng ta tạo thêm hai con trỏ, ab[0]ab[1], và chỉ cho họ ở cùng một vị trí như ab. Tức là, null.

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

All four pointers point to null

Sau đó, chúng tôi tạo mới Boolean truefalse đối tượng (với new Boolean(true)new Boolean(false) bộ phận của báo cáo).

Two new Booleans have been created

Cuối cùng, chúng ta để cho ab điểm đối với họ.

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

a and b point to the new Booleans

Khi bạn nhìn vào nó theo cách này, tôi nghĩ rằng đó là rõ ràng hơn tại sao thay đổi ab không ảnh hưởng đến mảng.

+0

minh họa đẹp.Bạn có thể tham gia đào tạo hoặc giảng dạy :) –

Các vấn đề liên quan