以下のクラスでは、ラッパークラスをプリミティブと比較しようとしましたが、結果が異なります。
次のリンクをチェックしました links :
より興味深い質問は、なぜ毎回一意のインスタンスを作成するために
new Object();
が必要なのかということです。私。 e。new Object();
がキャッシュできないのはなぜですか?答えはwait(...)
およびnotify(...)
呼び出しです。新しいObject()
sをキャッシュすると、スレッドが同期しないはずのスレッドが誤って同期されます。
新しいオブジェクトがある場合、a
とc
はどのように等しいですか?
b
がc
と等しく、c
がa
と等しい場合、a
はb
と等しいはずです。 。しかし、以下の場合、私はa != c
。
説明してください。
class WrapperCompare {
public static void main (String args[]) {
Integer a = new Integer(10);
Integer b = 10;
int c=10;
System.out.println(b==c); //true
System.out.println(a==b); //false
System.out.println(a==c); //true
}
}
更新:このリンクを参照して 整数キャッシュ 。
基本的に、IntegerクラスはIntegerインスタンスのキャッシュを-128から127の範囲で保持し、オートボクシング、リテラル、およびInteger.valueOf()の使用はすべて、そのキャッシュから対象範囲のインスタンスを返します。
したがって、この場合、すべてのステートメントが真であるべきです。
Integer
とint
を_==
_と比較する場合、Integer
をint
に変換する必要があります。これはunboxingと呼ばれます。
JLS§5.1.8 を参照してください:
r
がInteger
型の参照の場合、unboxing conversionはr
をr.intValue()
その時点で、int
とint
を比較しています。そして、プリミティブにはインスタンスの概念はありません。それらはすべて同じ値を参照します。したがって、結果はtrue
です。
だからあなたが持っている実際のコードは
_a.intValue() == c
_
_10 == 10
_の比較につながり、両方のint
値、Integer
インスタンスはもうありません。
Integer
とInteger
を比較すると、new Integer(...)
が実際に新しいインスタンスを作成していることがわかります。あなたはそれを_a == b
_で行いました。
コンストラクタnew Integer(...)
はdeprecatedです。代わりに_Integer#valueOf
_を使用する必要があります。これは潜在的に高速であり、内部キャッシュも使用します。 ドキュメント から:
指定された
Integer
値を表すint
インスタンスを返します。新しいIntegerインスタンスが必要ない場合、このメソッドは大幅に改善される可能性が高いため、コンストラクタInteger(int)
よりもこのメソッドを一般的に使用する必要がありますスペースと時間パフォーマンスbycaching頻繁に要求される値。このメソッドは常に_-128
_から_127
_までの範囲の値をキャッシュし、この範囲外の他の値をキャッシュする場合があります。
キャッシュは_==
_が再びtrueになるため(キャッシュされた値の場合)、ここで注意することが重要です。
_Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
_
キャッシングは、_-128
_と_+127
_の間の値に対して保証されていますが、他の値にも使用できます。
また、b
は実際にはキャッシュから取得されます。
_Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
_
したがって、boxingはInteger
sキャッシュを通過します( JLS§5.1.7 を参照)。