2016-05-08 11 views
0

Javaのランタイム定数プールには、次のリテラルが格納されています。 1)整数2)ロング3)フロート4)ダブル5)文字列。したがって、ブールリテラルと文字リテラルはどこに格納されていますか?Javaの同じ値を持つ参照2文字を比較します

例:

Character c1 = 'a'; 
Character c2 = 'a'; 
System.out.println(c1==c2); //prints true 

==は参照を比較するためには、C1とC2の共有と同じ参照していますか? (=これらのリテラルは、それらがそれぞれのプリミティブラッパークラスのオブジェクトであるように作成されることに留意されたい。

Character c1 = 'a'; 
Character c2 = c1; 

両方の参照が同じobject.Inに第二ケースポインティングと同様に

答えて

0
Character c1 = 'a'; 
Character c2 = 'a'; 

私が作成した、c1が、オブジェクト'a'を指しています参照変数であるC1、C2を参照。

参照変数について

詳しい説明を見つけることができるhere

さらに正確には、スタックメモリに名目上c1とc2という2つの参照変数を作成していますが、両方ともヒープメモリ内の同じオブジェクトを指しています。

+1

嫌いな人:私が間違って言ったことを親切に説明できますか? –

+0

'char'リテラルは、各行の' Character'クラスインスタンスに別々に自動ボクシングされます。 'Character'インスタンスが不変であると見ると、それらは使用時に影響を受けて「同じ」ですが、メモリ内の異なる場所を占有します。 – Ownaginatious

+0

使用されているJVM実装が、数えやすいプリミティブ(つまり、charとboolean)のボクシングされたインスタンスをキャッシュするほど洗練されているとは限りません。あなたが言っていることは必ずしも間違っているとは限らず、必ずしも必ずしも正しいとは限りません。それにかかわらず、あなたはその質問に答えていません。あなたの例では 'Character'を' Long'に変更してください。あなたが言ったことはもはや真実ではないでしょう。私はあなたを落胆させた人ではありません;) – Ownaginatious

2

あなたが言ったように、c1とc2は同じオブジェクトをヒープで共有しているため、比較は真です。これはJavaのキャッシュメカニズムです。すべての文字、-127〜127の範囲の値を持つ整数がキャッシュされます。 Javaは新しい値を作成する代わりに、キャッシュされた値を取得します。それで、両方のオブジェクトが同じ参照を共有しているのです。ここで

Character c1 = 'a'; 
Character c2 = 'a'; 
Character c3 = new Character('a'); // force Java creates new object in heap 
System.out.println(c1 == c2); -> true 
System.out.println(c1 == c3); -> false 

同じ理由で、別の例である:

Integer i1 = 127; 
Integer i2 = 127; 
System.out.println(i1 == i2); // true 
Integer i3 = 1000; 
Integer i4 = 1000; 
System.out.println(i3 == i4); // false, out of cache range 

あなたは、文字列のために、異なるメカニズムに別の例を満たしています:

String s1 = "stack"; 
String s2 = "stack"; 
String s3 = new String("stack"); 
System.out.println(s1 == s2); // true 
System.out.println(s1 == s3); // false 

すべてのJava文字列の作成時になります割り当てられ、String Poolに格納されます。新しい文字列を作成すると(s2の場合)、JavaはString poolを検索します。この文字列がすでにどこかに割り当てられているかどうかを調べます。 s3の場合、私たちはJavaに「こんにちは、Java、常に新しいものを作成してください」と言っています。

概要2つのオブジェクトを比較する場合、compareToメソッドを使用すると、2つのプリミティブを比較すると、==演算子を使用できます。 (古いJavaクラスを思い出させる)。

希望我々は、Javaのランタイム定数プールには、以下のリテラルを格納していることを知っている、このヘルプ:)

2

:1)整数2)ロング3)フロート4)ダブル5)文字列。

実際、これは正しくありません。正しい文は実際にautoboxed種類Booleanのそれぞれの値は、ByteShortCharacterIntegerLongのための別々のランタイム・プールがあるということです。ラッパー型のリテラルはを存在しないため

これらのプールは... リテラルのためではありません。これらの型のJavaリテラルはプリミティブ型の値です。 (実際には、明確なリテラルはJLSによると...種類byteまたはshortのためのすべてではありません。)FloatDoubleため

ありオートボクシングされませんプールは、それぞれのvalueOfメソッドのjavadocは思え何にもかかわらず、含意する。 JLSは、FloatDoubleのautoboxキャッシングを必要とせず、ライブラリは実装していません(少なくともJava 6,7,8では)。

注意すべきことは、オートボックによって生成されたすべての値がそれぞれのプールにあるとは限りません。たとえば、(デフォルトでは)Integerは-128〜+127の値をキャッシュします。

したがって、ブールリテラルと文字リテラルはどこに格納されていますか?

答えは上記から:

  • タイプBooleanCharacterのないリテラルはありません。 をオートボクシングにより作成BooleanCharacter
  • インスタンスがそれぞれのオートボクシング・プールから出てくることがあります。

そして、あなたの例:

==が参照を比較しているためには、C1とC2の共有と同じ参照していますか?

これは間違いありません。それは前の点を示しています。 Characterの自動ボックスプールは、'\u0000'から'\u007f'をキャッシュするために(JLSによって)必要です。


私はStringを省略しました。 Stringプールは(主に)文字列リテラルであるため、プールが異なります。一方、自動ボクシングは文字列の値には定義されていません...文字列の値は、プリミティブとラッパーの二分法と対立する必要はないからです。


1 - 知識をひけらかすことについて申し訳ありませんが、あなたが本当にこれらの事を理解し、それらについて他の人にコヒーレントに話をしたい場合は、正しいJava固有の用語を使用することが不可欠です。厳密に言うと、Literalは、プログラムの>>ソースコード< <に現れるものです。実行時には、対応するものは値です。

関連する問題