7

私は C++ でこのイディオムを定期的に使用しています。

/*return type*/ foo(/*parameters*/){
    static const char* bar = "Bar";
    /*some code here*/
}

内部的に、これは文字列リテラルのテーブルに追加されます。このJavaコードは同様のことを行いますか:

/*return type*/ foo(/*parameters*/){
    final String bar = "Bar";
    /*some code here*/
}

または、ここで無意識のうちに非効率性を導入していますか?

4

4 に答える 4

0

String.intern()次のように呼び出して、文字列をリテラル プール (Java ではインターンと呼ばれます) に追加するように指定できます。

final String bar = myString.intern();

これは基本的にリテラル プールと同じ概念であり、特定の文字列に対して同じオブジェクトを使用します。文字列リテラルは自動的にインターンされることに注意してください。また、インターンされた文字列を参照によって比較できるため、より効率的かもしれません。ただし、 を介して返された文字列を常に比較する必要がありますintern()。したがって

a.equals(b);

で置き換えることができます

a.intern() == b.intern();

実際には、上に示したとおりにしたくないことに注意してください。理想的には、インターンされた文字列を保持して再利用できます。ただし、インターンされた文字列にはいくつかの落とし穴があります。これらはガベージ コレクションではなく、メソッド自体は少し高価です。

于 2013-10-23T15:13:09.813 に答える
0

Java メソッドのfinalキーワードが、思ったとおりに動作しません。

この特定のケースでfinalは、変数を変更不可にします。それでおしまい。コンテンツ自体は文字列定数のグローバル テーブルに追加されますが、それへのポインタ (用語を許してください) は技術的に毎回設定されます。

このfinalキーワードは、主にメソッド内で、その後に作成する匿名クラスで変数を使用できるようにするのに役立ちます。それは、Java が「クロージャー」と見なしたいものに対する、お粗末な中途半端なサポートです。また、内部の匿名クラス内から外部の変数にアクセスできる唯一の方法でもあります。

final String bar = "Bar";
final Set<String> allTheBars = new HashSet<>() {{
    add(bar);
}};
于 2013-10-23T15:13:26.247 に答える