String、StringBuilder、StringBufferの詳細な説明


文字列クラス

文字列はJavaプログラミングで広く使用されています。文字列はJavaのオブジェクトです。Javaは文字列を作成および操作するためのStringクラスを提供します。

Stringの値は不変であるため、Stringに対する操作ごとに新しいStringオブジェクトが生成され、非効率的であるだけでなく、限られたメモリスペースを大量に浪費することに注意してください。

Stringクラスはfinalです。つまり、Stringクラスは継承できず、そのメンバーメソッドはデフォルトでfinalです。Javaでは、最終的に変更されたクラスを継承することはできず、クラスのメンバーメソッドはデフォルトでfinalメソッドになります。JVM実装の初期バージョンでは、実行効率を向上させるために、最終的に変更されたメソッドがインライン呼び出しに変換されます。Java SE5 / 6以降、このアプローチは徐々に廃止されてきました。したがって、現在のバージョンのJava SEでは、メソッド呼び出しの効率を向上させるためにfinalの使用を検討する必要はありません。メソッドを上書きしたくないことが確実な場合にのみ、メソッドをfinalに設定してください。

Stringクラスは、実際にはchar配列を介して文字列を保存します。

元の文字列に対してサブ操作、連結、置換操作のいずれも実行されませんが、新しい文字列オブジェクトが再生成されます。つまり、これらの操作を実行した後、元の文字列は変更されていません。

注:ここで常に1つのことを覚えておいてください。「文字列オブジェクトへの変更は元のオブジェクトに影響を与えず、関連する変更操作は新しいオブジェクトを生成します。」

文字列の深い理解

String str = "helloworld"とStringstr = new String( "hello world")の違いを分析することで、Stringクラスを深く理解することができます。

	public class Main {
    
    
	         
	    public static void main(String[] args) {
    
    
	        String str1 = "hello world";
	        String str2 = new String("hello world");
	        String str3 = "hello world";
	        String str4 = new String("hello world");
	         
	        System.out.println(str1==str2);
	        System.out.println(str1==str3);
	        System.out.println(str2==str4);
	    }
	}

出力結果は次のとおりです。

false
true
false

この結果は何を表していますか?

クラスファイルには、コンパイル時に生成されたリテラル定数とシンボル参照を格納するスペースの一部があります。この部分はクラスファイル定数プールと呼ばれ、実行時のメソッド領域の実行時定数プールに対応します。

したがって、上記のコードでは、String str1 = "helloworld";およびStringstr3 = "hello world";どちらもコンパイル中にリテラル定数とシンボル参照を生成し、実行時にリテラル定数 "helloworld"がランタイム定数に格納されます。プール(もちろん、1つのコピーのみが保持されます)。このように、Stringオブジェクトが参照にバインドされている場合、JVM実行エンジンは最初にランタイム定数プールで同じリテラル定数を検索します。存在する場合は、既存のリテラル定数への参照を直接指します。それ以外の場合。測定プールは、リテラル定数を格納するためのスペースを開き、リテラル定数への参照を指します。
  要約すると、newキーワードによるオブジェクト生成はヒープ領域で実行され、ヒープ領域でのオブジェクト生成のプロセスは、オブジェクトがすでに存在するかどうかを検出しません。したがって、newを使用してオブジェクトを作成する場合、文字列の内容が同じであっても、別のオブジェクトを作成する必要があります。


StringBuilderクラスとStringBufferクラス

Stringクラスとは異なり、StringBufferクラスとStringBuilderクラスのオブジェクトは、新しい未使用のオブジェクトを生成せずに何度も変更できます。

StringBuilderクラスはJava5で提案されました。これとStringBufferの最大の違いは、StringBuilderのメソッドがスレッドセーフではないことです。

StringBuilderはStringBufferに比べて速度が優れているため、ほとんどの場合、StringBuilderクラスを使用することをお勧めします。ただし、アプリケーションでスレッドセーフが必要な場合は、StringBufferクラスを使用する必要があります。

StringBufferオブジェクトが文字列バッファ内の複数のスレッドで使用されている場合、StringBufferの多くのメソッドがsynchronizedキーワードを持つことができるため、スレッドの安全性は保証されますが、StringBuilderメソッドにはこのキーワードがないため、スレッドの安全性は保証されません。 、操作が間違っている可能性があります。したがって、実行する操作がマルチスレッドの場合は、StringBufferを使用する必要がありますが、シングルスレッドの場合は、より高速なStringBuilderを使用することをお勧めします。


総括する

まず、実行速度、つまり実行速度について説明します。この点で、実行速度はStringBuilder> StringBuffer> Stringです。String
が最も遅い理由は、Stringが文字列定数であり、StringBuilderとStringBufferが両方とも文字列であるためです。変数、つまりStringオブジェクトが作成されると、オブジェクトは変更できず、StringBuilderとStringBufferのオブジェクトは変数です。変数を操作するには、操作を作成および再利用せずにオブジェクトを直接変更するため、速度はStringよりもはるかに高速です。
スレッドセーフの観点から、StringBuilderはスレッドセーフですが、StringBufferはスレッドセーフです。

文字列:少数の文字列操作に適しています。
StringBuilder:単一スレッドでの文字バッファーでの多数の操作に適しています。
StringBuffer:マルチスレッドで文字バッファに対して多数の操作が実行される状況に適用されます。


おすすめ

転載: blog.csdn.net/baidu_41847368/article/details/114699341