4

プライベート静的メソッド内の静的finalStringは、呼び出されたときに新しいオブジェクトをインスタンス化しますか?

private static String Test() {
    final String foo = "string literal";
    return foo;
}

または、コンパイラは、メソッド内に文字列リテラルが1つしかないことを知っていますか?または、それをプライベート静的最終クラスフィールドにする必要がありますか?これは、クラス全体にコードを分散させることにより、読みやすさを低下させる効果があります。

4

4 に答える 4

9

いいえ、特定の文字列は文字列リテラルプールから再利用されます。たとえば、次の場合:

final String foo = new String("string literal");

そうすれば、実際、メソッドが呼び出されるたびに新しいものが作成されます。

ここに証拠があります:

public static void main(String[] args) throws Exception {
    String s1 = test1();
    String s2 = test1();
    System.out.println(s1 == s2); // true

    String s3 = test2();
    String s4 = test2();
    System.out.println(s3 == s4); // false
}

private static String test1() {
    final String foo = "string literal";
    return foo;
}

private static String test2() {
    final String foo = new String("string literal");
    return foo;
}

finalこの特定のケースでは、修飾子は影響を与えないことに注意してください。変数の再割り当てを禁止するだけです。

于 2010-10-16T01:51:21.570 に答える
1

String文字列リテラルに対して作成されるaのインスタンスは1つだけです。Stringこれらは、クラスの「インターンプール」に保存されます。したがって、これらのString初期化を考えると:

String copy = new String("x");
String alias = copy.intern();

ステートメントcopy != "x"alias == "x"は両方とも真です。

この場合、フィールドがあればはるかに読みやすくなります。

于 2010-10-16T01:53:38.947 に答える
1

文字列リテラルについてあまり心配する必要はありません。文字列リテラルは、パフォーマンスを向上させ、メモリオーバーヘッドを削減するために、JVMによって特別に処理されます。コード内の任意の場所(ローカルまたはその他)で使用される文字列リテラルはプールされ、JVMによって再利用されます。これは、JVMで作成されるStringオブジェクトの数を減らすために行われます。コードが文字列リテラルを作成するたびに、JVMは最初にプール内の文字列リテラルをチェックします。文字列がすでにプールに存在する場合は、プールされたインスタンスへの参照が返されます。文字列がプールに存在しない場合は、新しいStringオブジェクトがインスタンス化されてから、プールに配置されます。文字列は不変であり、データの破損を恐れずに共有できるため、Javaはこの最適化を行うことができます。ただし、この動作は文字列リテラルにのみ当てはまり、「新しい」で作成されたオブジェクトには当てはまりません。

要約すると、文字列リテラルをクラス変数(プライベート静的最終クラスフィールド)にするか、ローカル変数として保持するかは同じ効果があります。

于 2010-10-16T02:04:29.103 に答える
0

fooはメソッド内のローカル変数であるため、関数が呼び出されるたびにインスタンス化されます。この特定の方法が静的であるという事実は関係ありません。fooがfinalであっても、インスタンス化されるタイミングには影響しません。これは、fooが最初の割り当て後に変更できないことを意味します。

プライベート静的クラス変数にして、インスタンス化が1回だけになるようにします。

于 2010-10-16T01:54:01.213 に答える