文字列インタビューの質問、これらの5つを読んだ後、あなたは何かを得ることを保証されています

 [推奨] 2020年のJava電子書籍の最新コレクション.pdf(吐血)>>>

 https://www.cnblogs.com/xiaogeng88/p/12692306.html

 

この記事では、Java Stringクラスに関する5つのインタビューの質問を見てみましょう。これらの5つの質問のうち、私はインタビュー中にいくつかの質問を個人的に経験しました。これを学んだ後、私はそれを理解し、なぜこの答えがあるのか​​を理解しました。この記事では、これらの質問に対する答えがそうである理由を理解することができます。

1.文字列型として定義されているst1とst2が等しいかどうかを判断する

パッケージ 文字列;

パブリッククラスDemo2_String {

  public static void main(String [] args) {
    String st1 =  "abc";
    文字列st2 =  "abc";
    System.out.println(st1 == st2);
    System.out.println(st1.equals(st2));
  }

}

出力:最初の行:true 2番目の行:true分析:最初の最初の印刷ステートメントを調べます。Javaでは、==この記号は比較演算子です。基本であれば、基本データ型と参照データ型が等しい場合があります。データ型の場合、==は値が等しいかどうかを比較し、それが参照データ型の場合、==は2つのオブジェクトのメモリアドレスが等しいかどうかを比較します。文字列は8の基本データ型に属していません。文字列オブジェクトは参照データ型に属しています。 "abc"は2つの文字列オブジェクトst1とst2に同時に割り当てられ、同じアドレスを指しているため、最初の出力はステートメントの==比較の出力はtrueです。次に、2番目のprintステートメントのequalsの比較を確認します。equalsはObjectの親クラスのメソッドであることがわかります。このequalsメソッドは、Stringクラスで書き換えられています。JDKAPIでは1.6ドキュメントのStringクラスの下でequalsメソッドを見つけてクリックし、「この文字列を指定されたオブジェクトと比較します。パラメータがでない場合に限りnull、この オブジェクトと同じ文字シーケンスを表すオブジェクトです。結果は次のようになります。「この同じ文字シーケンス、2つの配列、リスト、辞書の比較は、このロジックによって実装され、コードを記述します。st1とst2の値はどちらも「abc」であるため、2つは同じオブジェクトを指し、現在の文字シーケンスは同じなので、2行目の印刷結果もtrueになります。上記のコードを表すメモリグラフを描画してみましょう。 String true

メモリプロセスはおおよそ次のとおりです。1)最初に実行してコンパイルし、次に現在のクラスDemo2_String.classファイルをメモリのメソッド領域にロードします。2)2番目のステップでは、メインメソッドがスタックメモリにプッシュされます。3)定数プールが「abc」オブジェクトを作成し、メモリを生成します。アドレス4)次に、メインメソッドでメンバー変数st1に「abc」メモリアドレスを割り当てます。このとき、st1はメモリアドレスに従って定数プールの「abc」を指します。5)前の記事で述べたように、定数プールにはこの機能があります。存在することが判明した場合、重複オブジェクトは作成されません。6)定数プールに「abc」があるため、コードStringst2 = "abc"を実行すると、作成されません。 st27に「abc」メモリアドレスを直接割り当てます。最後に、st1とst2の両方がメモリ内の同じアドレスを指しているため、2つは同一です。2.次の文は、メモリ内にいくつかのオブジェクト作成します。答えは、メモリ内に2つのオブジェクトを作成します。1つはヒープメモリに、もう1つは定数プールにあります。ヒープメモリオブジェクトは、定数プールオブジェクトのコピーです。分析:すぐ下のメモリマップを見てみましょう。

newというキーワードが表示された場合、newから出てくるオブジェクトはすべてヒープメモリに格納されていると考える必要があります。次に、ヒープ内のオブジェクトが定数プール内のオブジェクトのコピーコピーである理由を説明します。「Abc」は文字列であり、文字列は定数なので、定数プールで作成する必要があります。したがって、最初に作成されるオブジェクトは定数プールで「abc」です。2番目のオブジェクトは、ヒープメモリ内のコピーのコピーです。これには、JDK API 1.6のString(String original)のコンストラクタに関するメモが必要です。新しく作成されたString オブジェクトを
初期化して、同じ文字シーケンス、つまり、新しく作成された文字列はパラメーター文字列のコピーです。それで、答えが出てきました、2つのオブジェクト。
3.文字列型として定義されている次のst1とst2が等しいかどうかを判断する

パッケージ 文字列;
パブリッククラスDemo2_String {
   public static void main(String [] args) {
     String st1 =  new String( "abc");
     文字列st2 =  "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}


回答:誤解と正解記憶分析に関するこれまでの2つの経験と理論のため、上記の答えはすぐにわかります。== st1オブジェクトとst2オブジェクトのメモリアドレスを比較します。st1はヒープメモリのアドレスを指しているため、st2は「abc」が定数プールにすでに存在していることを確認しているため、再度作成されないため、st2は定数プールのメモリアドレスを指します。したがって、==判定結果はfalseを出力し、2つは等しくありません。2番目の等しい比較。「abc」が1つしかないため、2つの文字列シーケンスが等しいかどうかの比較であり、完全に等しい。メモリマップは以下の通りです

4.文字列型として定義されている次のst1とst2が等しいかどうかを判断する

パッケージ 文字列;
 
パブリッククラスDemo2_String {
 
   public static void main(String [] args) {
     String st1 =  "a" +  "b" +  "c";
     文字列st2 =  "abc";
     System.out.println(st1 == st2);
     System.out.println(st1.equals(st2));
   }
}

答えはtrueとtrueの分析です。「a」、「b」、「c」は元々文字列定数であり、+記号が接合されると「abc」になり、「abc」自体は文字列定数です(Javaの場合)定数最適化メカニズムがあるため)、定数プールはすぐに "abc"文字列定数オブジェクトst2 = "abc"を作成します。このとき、定数プールは "abc"が存在するため、作成されません。したがって、メモリアドレスを比較する場合でも、文字列シーケンスを比較する場合でも、それらはすべて同じです。5.次のst2とst3が等しいかどうかを判断する

パッケージ 文字列;
 
パブリッククラスDemo2_String {
 
   public static void main(String [] args) {
     String st1 =  "ab";
     文字列st2 =  "abc";
     文字列st3 = st1 +  "c";
     System.out.println(st2 == st3);
     System.out.println(st2.equals(st3));
   }
}

答え:偽と真の分析:最初の答えは偽、2番目は真、2番目は真です。比較は「abc」であり、もう1つはスティッチングによって得られた「abc」であるため、非常によくわかります。つまり、比較と等しい、これは真の出力であり、非常によく理解しています。ですから、最初の判断はそれが間違っている理由です。私たちはとても困惑しています。同様に、APIアノテーションとメモリマップを使用して、これが等しくない理由を説明します。まず、JDK API 1.6でStringの概要を開き、下の図で文を見つけます。

重要な点は、赤い丸の中の文ですデータと文字列はすべてプラス(+)であり、結果は新しい文字列です。上記のコメントは、このスプライシングの原則がStringBuilderまたはStringBufferクラスと内部のappendメソッドによって達成され、次にtoString()が呼び出されてスプライスされたオブジェクトを文字列オブジェクトに変換し、最後に取得された文字列オブジェクトのアドレスが変数に割り当てられることを示しています。この理解と組み合わせて、メモリグラフを描画して分析します。

大まかなメモリプロセス
1)定数プールは「ab」オブジェクトを作成してst1に割り当てるため、st1は「ab」を指します2)定数プールは「abc」オブジェクトを作成してそれをst2に割り当てるため、st2は「abc」を指します3)理由ここでは+スティッチングメソッドを使用しているため、3番目のステップは、StringBufferクラスのappendメソッドを使用して「abc」を取得することです。このとき、メモリ0x0011はStringBufferオブジェクトを表します。これはStringオブジェクトではないことに注意してください。4)ObjectのtoStringメソッドを呼び出して、StringBufferオブジェクトをStringオブジェクトに置き換えます。5)文字列オブジェクト(0x0022)をst3に代入すると、2つのオブジェクトのメモリアドレスが異なるため、st =とst2 ==の判定結果は等しくなりません。概要:このインタビューの質問では、JDK APIの注釈と原則の一部をマスターし、メモリマップを分析して正しい結果を得ることが完全に必要です。メモリマップを描画することで、答えがこのようになっている理由を理解できることを認めます。メモリマップを描いた後、答えを得ると、非常に興味深いことがわかり、最後にそのような嘆きがあります。

おすすめ

転載: www.cnblogs.com/xiaogeng88/p/12692266.html