Javaにおけるequalsと==異同

4044 ワード

よりよく理解するために、まずjavaのデータ型javaのデータ型を見てみましょう. と 参照データ型.
基本データ型は8種類:数値型:byte int short long文字型:charブール型:bool
参照データ型は3種類あります:クラス:Classインタフェース:Interface配列:Array
なお、基本データ型には、自身に対応するパッケージクラス、すなわち参照タイプ:数値:Byte、Short、Integer、Long、Float、Double文字:Characterブール:Boolean
Javaでは、基本データ型が1つの領域(メモリのスタック)に統一されており、一部の領域は「定数プール」と呼ばれています.定数プールでは、基本データ型を共有できます.すなわち、int a=5を定義します.次にint b=5を定義します.このときaとbはメモリにおいて同じ5を指す.参照データ型の場合、参照データ型の変数は、この参照データ型の参照、すなわちアドレスを保存します.たとえば、String s=「abc」sはアドレスを保存します.
さて、本題に入ります.equalsと==の違いは簡単に言えば、equalsは値を比較し、==はアドレスを比較します.こんな前提で次のくだらない話を理解してあげます...
次のコードを見てください.
1 String s1 = new String("abc");

2 String s2 = "abc";

3 if(s1 == s2){

4   System.out.println("s1 == s2");

5 }

6 if(s1.equals(s2)){

7   System.out.println("s1 equals s2");

8 }

出力結果は、「s 1 equals s 2」です.なぜですか?s 1もs 2も「abc」なのに、「s 1!=s 2」なのか.
2つの文はいずれも1つのStringオブジェクトの参照を返すが、jvmの処理方法は異なる.1つ目の場合、jvmはすぐにheapにStringオブジェクトを作成し、そのオブジェクトの参照をユーザーに返します.2つ目の場合、jvmはまず内部メンテナンスstrings pool(文字列プールと呼ぶことができる)でStringのequelsメソッドによってstrings poolにStringオブジェクトが格納されているかどうかを検索し、存在する場合、heapで新しいStringオブジェクトを再作成することなく、既存のStringオブジェクトをユーザーに返します.strings poolにStringオブジェクトがない場合、jvmはheapに新しいStringオブジェクトを作成し、その参照をユーザーに返し、strings poolに追加します.注意:最初の方法でオブジェクトを作成する場合、jvmはプログラム呼び出しを行わない限り、strings poolにオブジェクトを自動的に配置しません. Stringのinternメソッド:str.intern()
internは、まずstrings poolに「abc」オブジェクトの参照があるかどうかを確認し、ある場合はその「abc」の参照を返します.いいえ、スタックにオブジェクトを新規作成し、strings poolに新しいオブジェクトの参照を追加します.
見覚えがあるのではないでしょうか.間違いありません.これは最初のコード例のString s 2=「abc」ではありません.の時にjvmがしたことですか.したがって、Stringで文字列を宣言すると、少なくとも1つのStringオブジェクトが存在します.これに対応する基本データ型のパッケージクラスには、Byte,Short,Integer,Long,Character,Booleanの2種類の浮動小数点数型のパッケージクラスでは実現されていない定数プール技術もある.また、Byte、Short、Integer、Long、Characterの5種類のパッケージクラスも、対応する値が127以下の場合にのみ使用できます.すなわち、オブジェクトは127以上のオブジェクトの作成と管理を担当しません.
原理を理解してから振り返ってみると、==:通常、int a=1という変数を定義することができます.int b = 1;aとbはいずれも基本データ型であり、定数プールに格納され、javaの定数プールが共有されているため、定数領域に1つしかないためif(a==b)はビットtrueに戻る.aとbの値もアドレスも等しいからです.△equalsはObjectクラスのメソッドであるため、equalsでは比較できません.
次にequalsを見てみましょう.前述したように、equalsはObjectクラスから継承されるメソッドであるため、すべての参照タイプでequalsメソッドを使用できます.次に、クラスのインスタンスを宣言してnewキーワードを使用するため、String str 1=「hello world」であることを覚えておいてください.String str2 = “hello world”; この2つは、newが使用されていないため、java仮想機会は基本的なタイプと同じように、定数プールに行って「hello world」が1つ存在するかどうかを確認し、あれば追加しないで、str 1、str 2はすべてこの「hello world」を指します.Stringオブジェクトをnewキーワードでインスタンス化できます.String s 1=new String(「abc」)です.String s2 = new String(“abc”).s 1とs 2は参照データ型であるためif(s 1.equals(s 2))はtrueを返し、if(s 1==s 2)はfalseを返す.これは,s 1とs 2はいずれもnewキーワードで宣言された新しいオブジェクトであり,それぞれの地盤があり,互いに関係がないためである.同じ値ですが、同じ名前の人が1階に2人いるように保存されている場所が異なりますが、2人は1つの部屋ではなく、操作に影響を与えません.だから==アドレスが同じかどうかを比較します.もちろんfalseです.これはまた,equalsが値を比較し,==がアドレスを比較していることを確認した.
また,Objectクラスにおけるequalsメソッドは,そのコードが==操作である.Objectのequalsメソッドが複写されていない場合に呼び出されると、==が使用されます.固有の参照データ型はStringクラスのようなequalsメソッドを複写した.
Objectクラスのequalsメソッド:
1 public boolean equals(Object obj) {

2     return (this == obj);

3 }