2013-10-15 21 views
13

誰もこのコードの結果が以下のような結果になる理由を説明できますか?ブール値の参照が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); 
    } 
} 

結果:

null 
null 

は、配列abには、物体オブジェクトBを、したがって出力するポインタを保持しているべきではない:

true 
false 
+3

ここでは、Javaがなくても変数が存在しないと不平を言うことができます。 P.S:@Testアノテーションに注目してください。 –

+3

私は簡潔さのために宣言を残しました。 – StuPointerException

+1

Ah shame。私は、テスト環境によって引き起こされたいくつかの "魔法"があると思いました。明らかにそうではありませんが、見知らぬものが見えます:) –

答えて

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

にこれは、オブジェクトの前にある、あなたは、オブジェクトへの参照をコピーし、割り当てるときに新しいステートメントで、新しいオブジェクトを作成し、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

私は、配列要素をポインタとして視覚化すると便利だと思います。

最初に、2つのポインタabを作成します。どちらもnullを指しています。

Boolean a = null, b = null; 

Pointers a and b point to null

次に、我々は2つのポインタ、ab[0]ab[1]を作成し、abと同じ場所でそれらを指します。つまり、nullです。

All four pointers point to null

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

はその後、我々は、(文の new Boolean(true)new Boolean(false)パーツ付き)新しいブール truefalseオブジェクトを作成します。

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

すてきなイラスト。あなたはトレーニングや教えに入ることができます:) –