Java String では、以下に示す 2 つの方法で作成できます。
String foo="Test";
String fooobj=new String("Test");
String を作成するこれら 2 つの方法の違いについてはどこでも言及されています。適切なシナリオとは何か、どこに行くべきかについてもっと知りたい
String foo="Test";
そして、いつ行くか
String fooobj=new String("Test"); ?
簡単な答え: 疑問がある場合は、必要ありませんnew String("literal here")
。必要な場合は、その必要性とその理由がわかります。
長い答え:
基本的に、使用したいのは、結果の文字列オブジェクトが他の文字new String("literal here")
列オブジェクトではないことを確認したい場合だけです。==
リテラルは自動的にインターンされます。経由で作成された文字列new String("literal here")
はありません。
では、なぜそれが欲しいのですか?インスタンスは不変であるため、インスタンスを他の何かとString
共有しているかどうかは気にしないためです。String
私が想像できるほぼ唯一のシナリオは、 を受け入れる API がありString
、 以外のフラグ値が必要で、次のようにnull
を介してそのフラグ/マーカー値を確認したい場合です。==
public static final String MARKER = new String("Marker");
public void someFictionalMethod(String arg) {
if (arg == MARKER) {
// Take action on the marker
}
else {
// Take action on the string
}
}
...そしてそれでも、私はそれが少し疑わしいと思う傾向があり、それを行う他の方法を模索します.
新しい String オブジェクトを作成する必要はありません
String fooobj = new String("Test");
したがって、これを行うべきではありません。String fooobj = "Test";
代わりに書いてください。
クラス String は不変です。つまり、String オブジェクトの内容は、作成後に変更することはできません。文字列リテラルの明示的なコピーを作成する必要はありません。
は絶対に使用しないでくださいnew String()
。この方法で文字列を作成するたびに、メモリ内に新しいオブジェクトが作成されます。と書くString s = "aaa"
と、そのようなオブジェクトが特定の JVM で既に作成されている可能性があり、文字列プールに格納されます。そのおかげで、変数はその既存のオブジェクトへの参照だけになります。この方法でメモリを保護します。
2 番目の方法を使用する場合、実際には最初の方法に依存してコンストラクターの引数を初期化します。
問題は、最初のアプローチで String オブジェクトを作成できる場合、なぜ 2 番目のアプローチを使用するために余分な労力を費やすのかということです。
2 番目のコンストラクター スタイルを使用するシナリオは見当たらないので、常に最初のアプローチを使用するように主張します。
String オブジェクトと文字列リテラルには微妙な違いがあります。
文字列 s = "abc"; // 1 つの String オブジェクトと 1 つの参照変数を作成する この単純なケースでは、"abc" がプールに入り、s がそれを参照します。
文字列 s = 新しい文字列 ("abc"); // 2 つのオブジェクトと 1 つの参照変数を作成します。この場合、new キーワードを使用したため、Java は通常の (非プール) メモリに新しい String オブジェクトを作成し、s がそれを参照します。さらに、リテラル「abc」がプールに配置されます。
文字列は定数です。作成後に値を変更することはできません。文字列バッファーは可変文字列をサポートします。String オブジェクトは不変であるため、共有できます。例えば:
String str = "abc";
次と同等です。
String str = new String("abc");
他の回答で説明されている理由により、文字列を宣言する2番目の方法は避ける必要があります