深さの浅い分析==とequalsの違い
4732 ワード
もしあなたが深く分析したことがなければ、これは非常に霊的な事件かもしれません.
霊異事件1:
霊異事件2:
霊異事件3:
霊異事件四:
NO.1 “==”
周知のように、==は、2つの変数が指すアドレスと値が同じかどうかを比較することである(もちろん指すアドレスが等しい場合、値も必然的に等しい).もちろん、基本データ型の比較であれば、値が等しい場合、trueを返す
したがって、これらの霊的なイベントを明らかにするには、メモリに格納され、実装されているソースコードを理解する必要があります.
基本データ型間の比較
Q:int e = 1111; int f = 1111; それぞれメモリで何をしましたか?
A:①、int e = 1111; スタックメモリに変数eが定義され、この変数はスタックメモリに1111を探しに行き、結果は(前に定義されていないため、見つからない)と考えられ、この1111をスタックメモリに追加する.
②、int f = 1111 ; このとき、スタックメモリに変数fが定義され、この変数はスタックメモリに1111を探しに行き、結果として(前のint e=1111の場合、入ったので)、1111を指します.
従って、e==fはtrue
参照データ型間の比較
注:霊異事象1~3を解読する
主に参照データ型ソースコードにおける自動梱包方法(valueOf)の具体的な実装を見て、その実装過程を分析する.
Q:Integer a = 111; Integer b = 111; 何をしましたか.A:ここでは自動梱包の過程について話しています.Integerの呼び出しに相当する.valueOf(int); 方法
Integerを見てvalueOf(int)のソース:
したがって、変数a,bは、キャッシュ内の同じオブジェクトを指す.a=bはtrue
ただし、変数c、dは[-128-127]のキャッシュ範囲を超えているため、スタックメモリに新しいIntegerオブジェクトがそれぞれ作成されます.したがってc==dはfalseである.
ポイントは次のとおりです.
注意:Boolean:直接比較値;Byte:すべてキャッシュを探します;Character:asciiコード値<=127のキャッシュを探します;Short、Long、Integer:[-128127]区間の値、キャッシュを探します;Float、Double:キャッシュを探さないで、直接新しいオブジェクトを作成します
Stirngタイプ(霊異イベント4用)Stringに対してもキャッシュメカニズム(定数プール)が提供される.
Q:String a = "abc";String b = "abc"; String c = new String("abc"); 別々に何をしましたか.
A:①、String a = "abc"; スタックメモリに変数aを定義し、定数プールに「abc」を探し、見つからない場合は「abc」を定数プールに格納します.
②、String b = "abc"; また、スタックメモリに変数bが定義され、定数プールに「abc」が検索され、変数bについて定数プールの「abc」が参照される.
③、String c = new String("abc"); またスタックメモリに変数cを定義し、定数プールで「abc」を探します.i、見つかった場合、スタックメモリのnew 1つのStringオブジェクトで定数プールの「abc」参照を渡すだけです.ii、見つからない場合は、オブジェクト「abc」を作成して定数プールに格納し、スタックメモリにオブジェクトを作成し、定数プールの「abc」参照を転送する.
したがってa==bはtrueである.a==c&&b==cはfalse
対象:String d=String.valueOf("abc"); ,ソースコードを確認して復号します.
したがって、ここで変数dは定数プール内の「abc」を指し、a==dはtrueである.
NO.2 “equals”
よく知られているように、Objectはすべてのクラスの親であり、すなわち、Objectのequals()メソッドを呼び出すか、そのクラスが書き換えたequals()メソッドを呼び出すかのいずれかである.
Object.equals():=の比較結果(アドレスと値の比較)を返します.
String.equals():値の比較
結論
①、== 2つの変数が指すアドレスと値が同じかどうかを比較する.基本データ型は値を比較します.②、Object.equals()は、==の比較結果(アドレスと値の比較)を返します.3、equals()メソッドを書き換えたもの:具体的な実装を確認する必要があります.たとえばString書き換えのequals()メソッドは,比較すると値である.
霊異事件1:
Integer a = 111; // Integer a = Integer.valueOf(111);
Integer b = 111;
Integer c = 1111;
Integer d = 1111;
int e = 11111;
int f = 11111;
System.out.println(a==b); // true
System.out.println(c==d); // false
System.out.println(e==f); // true
霊異事件2:
double a = 1.0;
double b = 1.0;
Double c = 1.0;
Double d = 1.0;
System.out.println(a==b); // true
System.out.println(c==d); // false
霊異事件3:
Character a = 'A';
Character b = 'A';
Character c = '√';
Character d = '√';
System.out.println(a==b); // true
System.out.println(c==d); // false
霊異事件四:
String a = "abc";
String b = "abc";
String c = new String("abc");
String d = String.valueOf("abc");
System.out.println(a==b); // true
System.out.println(b==c); // false
System.out.println(b==d); // true
System.out.println(c==d); // false
NO.1 “==”
周知のように、==は、2つの変数が指すアドレスと値が同じかどうかを比較することである(もちろん指すアドレスが等しい場合、値も必然的に等しい).もちろん、基本データ型の比較であれば、値が等しい場合、trueを返す
したがって、これらの霊的なイベントを明らかにするには、メモリに格納され、実装されているソースコードを理解する必要があります.
基本データ型間の比較
Q:int e = 1111; int f = 1111; それぞれメモリで何をしましたか?
A:①、int e = 1111; スタックメモリに変数eが定義され、この変数はスタックメモリに1111を探しに行き、結果は(前に定義されていないため、見つからない)と考えられ、この1111をスタックメモリに追加する.
②、int f = 1111 ; このとき、スタックメモリに変数fが定義され、この変数はスタックメモリに1111を探しに行き、結果として(前のint e=1111の場合、入ったので)、1111を指します.
従って、e==fはtrue
参照データ型間の比較
注:霊異事象1~3を解読する
主に参照データ型ソースコードにおける自動梱包方法(valueOf)の具体的な実装を見て、その実装過程を分析する.
Q:Integer a = 111; Integer b = 111; 何をしましたか.A:ここでは自動梱包の過程について話しています.Integerの呼び出しに相当する.valueOf(int); 方法
Integerを見てvalueOf(int)のソース:
public static Integer valueOf(int i) {
// -128 <= i <= 127,
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
したがって、変数a,bは、キャッシュ内の同じオブジェクトを指す.a=bはtrue
ただし、変数c、dは[-128-127]のキャッシュ範囲を超えているため、スタックメモリに新しいIntegerオブジェクトがそれぞれ作成されます.したがってc==dはfalseである.
ポイントは次のとおりです.
注意:Boolean:直接比較値;Byte:すべてキャッシュを探します;Character:asciiコード値<=127のキャッシュを探します;Short、Long、Integer:[-128127]区間の値、キャッシュを探します;Float、Double:キャッシュを探さないで、直接新しいオブジェクトを作成します
Stirngタイプ(霊異イベント4用)Stringに対してもキャッシュメカニズム(定数プール)が提供される.
Q:String a = "abc";String b = "abc"; String c = new String("abc"); 別々に何をしましたか.
A:①、String a = "abc"; スタックメモリに変数aを定義し、定数プールに「abc」を探し、見つからない場合は「abc」を定数プールに格納します.
②、String b = "abc"; また、スタックメモリに変数bが定義され、定数プールに「abc」が検索され、変数bについて定数プールの「abc」が参照される.
③、String c = new String("abc"); またスタックメモリに変数cを定義し、定数プールで「abc」を探します.i、見つかった場合、スタックメモリのnew 1つのStringオブジェクトで定数プールの「abc」参照を渡すだけです.ii、見つからない場合は、オブジェクト「abc」を作成して定数プールに格納し、スタックメモリにオブジェクトを作成し、定数プールの「abc」参照を転送する.
したがってa==bはtrueである.a==c&&b==cはfalse
対象:String d=String.valueOf("abc"); ,ソースコードを確認して復号します.
public static String valueOf(Object obj) {
// String toString() ,
return (obj == null) ? "null" : obj.toString();
}
public String toString() {
return this;
}
したがって、ここで変数dは定数プール内の「abc」を指し、a==dはtrueである.
NO.2 “equals”
よく知られているように、Objectはすべてのクラスの親であり、すなわち、Objectのequals()メソッドを呼び出すか、そのクラスが書き換えたequals()メソッドを呼び出すかのいずれかである.
Object.equals():=の比較結果(アドレスと値の比較)を返します.
public boolean equals(Object obj) {
return (this == obj);
}
String.equals():値の比較
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
結論
①、== 2つの変数が指すアドレスと値が同じかどうかを比較する.基本データ型は値を比較します.②、Object.equals()は、==の比較結果(アドレスと値の比較)を返します.3、equals()メソッドを書き換えたもの:具体的な実装を確認する必要があります.たとえばString書き換えのequals()メソッドは,比較すると値である.