2013-10-15 48 views
13

任何人都可以解释为什么此代码导致下面的输出吗?布尔引用为空

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

结果:

null 
null 

应该AB不保持指针数组对象a和对象b,因此输出:

true 
false 
+3

现在的技巧问题是,如何在没有Java抱怨它们不存在的情况下分配变量:p。 P.S:注意@Test注释。 –

+3

为了简洁起见,我放弃了声明 - 没有什么有趣的在那里看到! – StuPointerException

+1

啊惭愧。我认为测试环境引起了一些“魔力”。显然不是这种情况,但看到陌生人的东西:) –

回答

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

这不会改变a和b指向的对象(数组中的元素)。它将它们指向new对象。

它不modfying阵列

为了说明:

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和d将仍然是真/假分别。这与数组发生的情况是一样的,除非数组引用的命名方式不同。

+3

嗡嗡声杀/正确的措辞时间。上面的代码确实改变了'a'和'b'指向的对象。但是,它不会更改从'a'和'b'('null')复制的数组元素引用指向的对象。 –

+0

@SotiriosDelimanolis重写了澄清 – Cruncher

+3

@SotiriosDelimanolis正在思考这个问题,它实际上只是语言上的含混(还没有更好地阐明)。如果我做'a.change()',我可以说:'我改变了一个点的对象'。如果我做了'a = new Object();',我可以说:'我改变了指向'的对象。只是一个人在谈论这个参考,而另一个则是这个客体。 – Cruncher

8

你必须在分配它们之前初始化你的布尔值。

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

这是之前的对象,你复制的参照对象,并使用新的语句,创建一个新的对象,第一个A,B分配时是空值。

3

......这是绝对正常的。您正在初始化值,但依次说,在进程分配变量之前,ab仍然是null。这不是放置的变量,而是它们的值或引用作为数组中的元素。

@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

您的代码展开:

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

当下变量的内容命名为a和b是复制到阵列中,它被设置为null。 之间有一个重要的区别,请参考。作为一个侧面说明:建议使用Boolean.TRUE,或者至少使用Boolean.valueOf(true)来避免不必要的对象创建。对于布尔值没有太多的选项,布尔值是不可变的

+0

+1我喜欢这样。跳过一些语法糖,并显示它与我的答案中的示例没有什么不同。 – Cruncher

4

我认为将数组元素可视化为指针是有帮助的。

我们首先创建两个指针,ab,它们都指向null。

Boolean a = null, b = null; 

Pointers a and b point to null

接下来,我们创建两个三分球,ab[0]ab[1],并在同一个地方ab指向他们。那就是,null

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

All four pointers point to null

然后,我们创造新的布尔truefalse对象(与new Boolean(true)new Boolean(false)部分语句)。

Two new Booleans have been created

最后,我们让ab点给他们。

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

a and b point to the new Booleans

当你看到它这样,我觉得它更清楚为什么改变ab有阵没有影响。

+0

好例证。你可以参加培训或教学:) –