0

JavaでのStringzインスタンスプーリングに関する簡単な質問がありました

このような状況が発生した場合:シナリオ1:

String s1 = "aaa";  
String s2 = new String("aaa");  

次に、シナリオ2を反転します。

String s1 = new String("aaa");  
String s2 = "aaa";  

いずれの場合も、文字列プールとヒープにいくつのオブジェクトが作成されていますか?両方が同じ数のオブジェクトを作成すると仮定しました(2つのオブジェクト-文字列プールの各シナリオの両方の行に1つの「aaa」と新しい演算子に1つ)。私はこれが正しくなかったとiviewで言われました-私は私の理解の何が悪いのか知りたいですか?

4

2 に答える 2

1

答えは、インタビューで述べたように、いずれの場合も、ヒープに 1 つのインスタンスと String プールに 1 つのインスタンスです。

文字列が存在できるスペースは 2 つあります。インターンされた文字列が格納されるヒープと perm gen です。

String コンストラクターは、ヒープに String を作成します。文字列リテラルは、永続世代内の文字列プールに作成されます。ヒープ内の文字列はString.intern()、文字列をインターンする (つまり、プール内の等しい文字列への参照を決定するか、プール内に等しい文字列がまだ存在しない場合はそこに等しい文字列を作成する) メソッドを使用して、文字列プールに移動できます。インターンされた文字列。

編集:私が答えたことを確認するには、System.out.println(s1 == s2);各例に3行目を追加してください。どちらの場合も false を出力し、両方のオブジェクトが異なるメモリ アドレスを持っていることを証明します。

于 2012-04-06T15:51:59.930 に答える
1

リテラルの文字列は"aaa"、クラスがロードされるときに作成およびプールされるため、2 行のコードが実行されるときに新しい文字列が 1 つだけ作成されます。

明確にするために: どちらの例も、実行時に新しい String オブジェクトを 1 つだけ作成します。リテラルは、文字列「aaa」を含むクラスが初めて使用されるときに作成されます。

class FooBar{
  void foo(){
    String s1 = "aaa";//the literal already exists  
    String s2 = new String("aaa");//creates string for s2 
  }
  void bar(){
    String s1 = new String("aaa"); //creates string for s1 
    String s2 = "aaa";//the literal already exists  
  }
}

class Test{

    public void main(String... args){
      ...
      //first time class FooBar used in program, class with literals loaded
      FooBar fb = new FooBar();
      //creates one string object, the literal is already loaded
      fb.bar();
      //also creates one string object, the literal is already loaded
      fb.foo();
    }
}
于 2012-04-06T15:35:14.047 に答える