String、StringBuffer、StringBuilderの違いは何ですか?


概要


JAVAでは、文字列クラスにはString、StringBuffer、StringBuilderが含まれます.
しかし、この3つにはそれぞれ違いがあり、理解と使用を学ばなければならない.この文章はその違いをまとめる.

String


Stringは不変オブジェクトと呼ばれます.このStringオブジェクトは、JVMのString constant poolに格納してもよいし、Heap領域に格納してもよい.

1.文字の使い方

String str = "Hello";
文字で作成された場合、String constant poolに格納され、内部でintern()という関数が実行されます.
intern()String constant poolを検索し、同じ内容の文字列があるかどうかを検索します.
同じ内容の文字列がある場合は、その文字列のアドレス値を返して再利用します.
ない場合は、String constant poolに再割り当てし、アドレス値を返します.
すなわち、下図に示すように、strとstr 2を同じ内容で文字で宣言すると、同じアドレス値を有する.
String str = "Hello";
String str2 = "Hello";

上記のコードではstrとstr 2は同じアドレス値を表す.
str=str 2はtrueを返します.したがって,文字生成文字列を比較する際にstr.equals(str 2)を用いて比較する必要はない.

2.new演算子の使用


これに対して、new演算子を使用してheap領域に個別のインスタンスを作成し、個別のアドレス値を指定します.
String str = new String("hello");

JAVA 7版では、String Constant PoolはPerm領域に属しており、GCの目標ではないため、OOME問題が頻繁に発生している.
しかしJAVA 7バージョンからString Constant poolがHeapエリアに移動し、GCのターゲットとなり、ある程度問題が解決した.
注-なぜJAVA 8でperm領域が消え、metaspace領域に取って代わられたのですか?
Retrilとして宣言されたStringを説明する場合、内部にはintern()メソッドがあります.では、実際にテストコードを振り返り、説明した内容が正しいかどうかを確認しました.
 @Test
  public void intern_test(){
    String str1 = new String("d");
    String str2 = "a";
    String str3 = "a";
    Assertions.assertTrue(str2 == str3);
    Assertions.assertFalse(str1 == "d");
    Assertions.assertTrue(str1.intern() == "d");
  }

まず、同じ内容の文字を==と比較して、本当に現れるかどうかを確認します.
同じ内容ですが、生成された文字列を==を使用した新しい演算子と比較して異なる内容を特定し、new演算子を使用して生成された文字列上でintern()メソッドを実行すると、同じ内容の新しい文字列と比較すると、本当にこのような状況になるのではないでしょうか.これについても確認した.
さらに、Stringは宣言されると一定の特性を保持する.
文字列を変更する場合は、実際には文字列を変更するのではなく、新しい文字列を割り当てます.

文字列を頻繁に追加、修正または削除すると、大量のGarbageが発生し、臀部領域のメモリが不足する可能性があります.
したがって、文字列が頻繁に変化する場合は、他の方法を使用します.

StringBuilder, StringBuffer


上記の問題を改善するために、StringBuilderクラスとStringBufferクラスを使用することができます.
このクラスは可変で、文字列の追加、修正、削除に有利です.
ここにもこの2つの違いがあります.それはthread-safeの違いです.

StringBuffer


StringBufferクラスは内部で同期キーを使用するため、マルチスレッド環境では安全です.

StringBuilder


StringBuilderはクラスで同期キーを使用しないため、マルチスレッド環境では使用できません.
逆に、StringBuilderの性能はThread-Safe StringBufferよりも速い.

n/a.結論


つまり、文字列が頻繁に変化する場合、StringよりもStringBuffer、StringBuilderクラスの方が良く、現在の環境がマルチスレッド環境であるかシングルスレッド環境であるかによって、どの文字列クラスを使用するかを選択します.