2012-01-25 7 views
5

私はこの質問をした:どのように多くの参照変数は、以下のコードのprintlnの声明より前に作成されたどのように多くのStringオブジェクトと上記の詳細に基づいてJavaはどのようにメモリ内のStringオブジェクトを処理しますか?

String s = "abc"; // creates one String object and one 
      // reference variable 
In this simple case, "abc" will go in the pool and s will refer to it. 
String s = new String("abc"); // creates two objects, 
       // and one reference variable* 

String s1 = "spring "; 
String s2 = s1 + "summer "; 
s1.concat("fall "); 
s2.concat(s1); 
s1 += "winter "; 
System.out.println(s1 + " " + s2); 

私の答え2つの参照変数、S1、S2があり、このコードフラグメントの結果は、春冬春夏

ある ました。 「春」、「夏」(紛失)、「春夏」、「秋」(迷子)、「春 秋」、「春夏春」の合計8つのStringオブジェクト が作成されました。 (紛失)、「冬」(紛失)、「春冬」(この時点で「春」は失われている)。

このプロセスでは、8つのStringオブジェクトのうち2つだけが失われません。

正しいですか?

+0

知るには良い何か:http://stackoverflow.com/questions/7663252/java-string-concat-in-stringbuilder-call/この質問に対する私の答えは間違っていたことに注意してください... – Gevorg

答えて

3

答えは:2つの参照と8つのオブジェクト

String s1 = "spring "; //One reference and 1 object in string pool. (if it didn't exist already) 

String s2 = s1 + "summer "; //Two references and 3 objects 

s1.concat("fall "); //Two references and 5 objects 

s2.concat(s1); //Two references and 6 objects 

s1 += "winter "; //Two references and 8 objects 

System.out.println(s1 + " " + s2); 

今あなたの質問:どのようにメモリ内のJavaハンドルStringオブジェクトを行い

Javaは、クラスStringのオブジェクトを作成する2つの方法を提供します。

  1. 文字列str1 = "OneString";

この場合、JVMは文字列プールを検索して、同等の文字列がすでに存在するかどうかを確認します。そうであれば、同じものへの参照を返します。そうでない場合は、文字列プールに追加して参照を返します。 新しいオブジェクトが作成されるか、そうでない可能性があります。

  1. 文字列str1 =新しい文字列( "OneString");

ここで、JVMはヒープ上にオブジェクトを作成する必要があります。 新しいのため。 OneStringがすでに文字列プールに存在するかどうかは関係ありません。

また、プールに文字列を置くことができます:あなたはStringオブジェクトのインターン()を呼び出すことができます

。これにより、プールにStringオブジェクトが格納されていなければStringオブジェクトが格納され、プールされた文字列への参照が返されます。 (すでにプールに入っていた場合は、既に存在していたオブジェクトへの参照を返します)。

あなたは以下のリンクを見てするようなことがあります。オブジェクトが既に文字列定数プールに存在しない場合のみ、

What is the Java string pool and how is "s" different from new String("s")?

Questions about Java's String pool

1

正しく表示されます。これはSCJPの試験問題です。

concatは新しい文字列を返しますが、これは失われます。文字列内に存在することもできる

  • 文字列を(既にあなたによって説明したように)

    • 文字列は不変です: 最初s1は、「春の冬」は、Javaの文字列について知っておくべき

      2つのことで上書きされますプール。あなたが "Summer"という全く新しいString Stringを作成するたびに、不変の "Summer"がプールから出るかもしれません(JVMに依存しますが、Oracleにとってはそうです)。参照:Javaでhttp://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern()

    乾杯 クリスチャン

  • +0

    あなたはもっと上のコメントでしたあなたが新しいString( "Summer")を書くたびに、まったく新しい文字列ist construct_? "new"を使用すると、**新しいjava.lang.String **オブジェクトが構築されなければなりません(つまり、==でそれらを比較する場合、2つの文字列は同じではありません)。ただし、これらの2つの異なるStringインスタンスは、特定の条件下で基になるchar []配列を共有できます。 –

    +0

    はい、私はすぐに入力しました。あなたが正しいです、文字列オブジェクトが構築されています - 文字列プール内にあるため、 "文字列"自体がメモリを必要としないことを意味しました。 http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern()も参照してください。 – Christian

    1

    文字列は不変です。割り当てられた文字配列と、オフセットや長さなどの周辺情報があります。文字列リテラルを使用して文字列を初期化する場合、コンパイラは最適化を試み、リテラルごとに1つの文字列オブジェクトのみを作成します。これは不変であるため可能です。

    あなたは、文字列に連結を行うか、+場合は、パフォーマンス上のペナルティで(その後、新しい文字列がalloactedされ、データが一緒にcompied

    これに対し

    、文字列から部分文字列を作成することは事実上自由である - 。データはコピーされません

    1
    String s = "abc"; // creates one String object and one 
           // reference variable 
    

    は、1つの文字列オブジェクトを作成します。 。

    String s = new String("abc"); // creates two objects, 
               // and one reference variable* 
    

    実際には、ヒープ内に1つのオブジェクトしか作成されません。このStringオブジェクトに対してintern()メソッドが呼び出された場合にのみ、このオブジェクトをプールに追加します。

    String s1 = "spring "; 
    String s2 = s1 + "summer ";   
    s1.concat("fall ");   
    s2.concat(s1);   
    s1 += "winter "; 
    System.out.println(s1 + " " + s2); 
    

    あなたの説明が:-)。あなたがするSystem.out.println()内の1つの以上の文字列を持っている以外、
    あなたはそれが実際にはより多くのライブオブジェクトがあることを意味しない(失われた)と言う(の参照をOKと思われますスタックに存在しません)。

    関連する問題