文字列のJavaコードのシンプルなピースは、実際にたくさんのことを学びました

以下の結果を実行するコードは何ですか?これらの違いがある理由を説明します。

文字列S1 = "こんにちは"; 
文字列s2を= S1 + "世界";
文字列S3 = "こんにちは" + "世界";
文字列S4 = "こんにちは、世界";
文字列S5 =新しい文字列( "こんにちは、世界");

System.out.println(s2.equals(S4))。//真
のSystem.out.println(S2 == S4)。//偽
のSystem.out.println(S3 == S4)。//真
のSystem.out.println(S4 == S5)。//偽

一見単純なコード、その中の多くの知識があります。JVMのヒープとスタックについてその最初の非常に簡単に話の前に、スタックは、一般的にも、文字列定数プールのjdk1.7バージョンの後に、ローカル変数、オブジェクト参照、等、等の一般的なリリースヒープオブジェクト、定数、に保存されていますヒープインチ

文字列定数プール

  通常の状況下では、二つの方法で文字列オブジェクトを作成し、1リテラル作成され、1は2が同じではない、新しい創造です。

  それは、このような文字列S4 =「こんにちは、世界」として、リテラルの道を作成することであるならば、それはS4に取り組むそうならば、JVMは、プールに行くと、任意の文字列定数は「hello、world」の文字列を探しています。もしいいえ、それは最初の定数プール「こんにちは、世界」で作成し、その後、S4にアドレスされ;及び方法で新しいオブジェクトを作成し、それが「こんにちは、世界」オブジェクトは、このオブジェクトへのS5ポイントを作成するために、ヒープです。それを図や、より直感的に:

  

(等しい)と== 

  これはJavaのインタビュー、多くの場合、テストサイトで、それは一時停止または殴られるまで(はい、私は)インタビュアーが正直にオブジェクトを見ていきますいくつかはイコール()の値を比較すると言うかもしれない、との比較は==オブジェクト参照ですソースコードのクラスのequals():

    

  等しい()メソッド本体を見ることができ、戻り二つの参照オブジェクトの比較の結果を表示します。しかし、String型==とequals()の二人は時々 、結果は同じではありません。Stringクラスには、等しいので、それは()に書き換えられています。

  

  これは、最初の2つの比較参照することがわかる。同じ場合は直接その値と同じではない、真を返します。したがって、私たちはより良い==とequals()を区別することができます。

  

文字列のスプライシング

  最終Stringクラスは、文字列の2つの方法のその後のappend()文字列の連結、二つの文字列が氏StringBuilderオブジェクトに追加されたときに、変更することができないので、修飾し、新しいを生成するためのtoString()メソッドを呼び出しています文字列オブジェクト。だから、彼らはJVMであるs1とs2を考慮すると、この次のとおりです。

  

  但是像 String s3 = "hello" + ",world" 这样直接两个字面值相加的,java文件在编译期间就已经将这条语句做了优化,将其直接变成 "hello,world",等到运行的时候就查找字符串常量池,因此 s3 == s4 返回的结果就为 true。

String、StringBuilder、StringBuffer

  既然上面说到了 StringBuilder,那就顺便简单说一下这三者之间的区别。

  String 是常量,且每次需要在原来字符串基础上扩展都需要新建对象,导致速度会稍微慢一点,而且占内存,因此对于需要经常扩展的字符串,可以使用 StringBuilder 和 StringBuffer。但是 StringBuilder 和 StringBuffer 又有区别,即时两者很像,在速度上 StringBuilder 会快一些,因为 StringBuffer 的操作加了 synchronized ,即加了锁,使得操作相对比较慢,就举 append() 为例子,StringBuffer 中此方法的源码如下:

  

   所以,一般在单线程的情况下,可以选择使用 StringBuilder;在多线程的情况下可以选择 StringBuffer .

总结

  回到一开始的程序,我们可以大致地画出在 JVM 中的存储:

   

 

  

おすすめ

転載: www.cnblogs.com/lyuzt/p/12075568.html