2013-01-21 2 views
16

私は2つの質問がある:プールはいつ変更されますか?

public static void main(String[] args) { 
    String s1 = "bla"; 
    String s2 = "b" +"l" + "a"; 
    String s3 = "b".concat("l").concat("a"); 

    if(s1 == s2) 
     System.out.println("Equal"); 
    else 
     System.out.println("Not equal"); 
    if(s1 == s3) 
     System.out.println("Equal"); 
    else 
     System.out.println("Not equal"); 
} 
  • なぜs1と同じオブジェクトへs2ポイント、s1s3がないのに対し、していますか? (newキーワードの使用はありません)。

  • 私は、ユーザからの文字列を取得し、上記のコードにこれらの行を追加した場合:ユーザーは、ユーザーが別のもののプログラムの出力を入力したときにxyzプログラムは、Not equalを印刷します入ると

    BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); 
    String name=in.readLine(); 
    if(name.equals("test")) 
        s1 = s1 + "xyz"; 
    

    Equal 。これはプログラム全体の実行によってプールが変化することを意味しますか?オプティマイザはコンパイル時に機能し、runtimeで引き続き動作しますか?

答えて

15

なぜs1とs2は同じオブジェクトを指していますが、s1とs3は同じオブジェクトを指していませんか? (新しいキーワードの使用はありません)。

連結はコンパイル時に行われるため、完成した文字列は最初の例と同じ定数プールに格納されます。これは、コンパイラにとって「知られている」特殊なケースです。これは実際には、このように複数の行にまたがって連結された長い文字列が、単純な文字列定数と同じパフォーマンス向上の利点を得るようにすることを意味します。

実行時に計算を実行するので、定数プールの一部にはなりません。

しかし、文字列定数プールにできるかどうかの詳細は意図的に曖昧に残っているため、さまざまな実装方法が異なる方法で最適化される可能性があります。にはが含まれていますが、この動作は実装全体で一貫しているとは限りません。

9

S1とS3 がないのに対し、なぜ、同じオブジェクトをs1とs2ポイントしていますか? (新しいキーワードの使用はありません)。 JavaでString以来

Immutableなので、文字列クラスのいずれかの方法は、(いくつかの例外ががあります - 1はsubstring方法で)新しいStringオブジェクトを返します。したがって、concatメソッドは、ヒープに移動し、定数プールに追加されない新しい文字列を作成します。

は限りs1s2の場合に関しては、両方の文字列を、時間をコンパイルで知られており、したがってそれらは同じ文字列リテラルです。

なお、第2列に連結演算: -

String s2 = "b" +"l" + "a"; 

はコンパイル時に評価され、結果は最初の文字列と同じであることが知られており、一つのエントリが一定になりますプール。

3

時々(実行時にStringの値が何であるかはコンパイラにとって明らかです)、コンパイラはStringプールを使用しますが、そうでない場合はStringプールを使用します。

実際には、あなたのコードは、プールを使用しているか使用していないかによって決まります。

あなたの文字列プールから使用されているかどうかを確認したい場合は、てjavapリストを使用してコードをコンパイルすることができますので、あなたは常に、メイン実行することはできませんが、比較的自明です。

関連する問題