2016-12-07 10 views
-3
public static void main(String[] args) { 
     String a = new String("abc"); 
     String b = "abc"; 
     String c = "abc" + "KDF" + "gh" +"rt" +"jk"; 

    } 

下記のコードのバイトコードをご覧ください。以下のコードで作成されたStringオブジェクトの総数?

Compiled from "NumOfStringObject.java" 
public class com.practise.general.NumOfStringObject extends java.lang.Object{ 
public com.practise.general.NumOfStringObject(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: new  #2; //class java/lang/String 
    3: dup 
    4: ldc  #3; //String abc 
    6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin 
g;)V 
    9: astore_1 
    10: ldc  #3; //String abc 
    12: astore_2 
    13: ldc  #5; //String abcKDFghrtjk 
    15: astore_3 
    16: return 

} 

私は私が3つのStringオブジェクトの合計が作成なっていると思い、読み/理解バイトコードでの経験がありません。

あなたの考えを教えてください。

+0

あなたが作成する文字列 – XtremeBaumer

+0

ありがとうしかし、なぜ "KDF"、 "gh"、 "rt"、 "jk"のような中間オブジェクトが文字列プールに格納されていないのですか? – Lovesh

+0

@Loveshこの動作が定義されている仕様へのリンクを教えました – xenteros

答えて

-4

文字列は、ここでの議論を読む不変

です。あなたを助けなければならない。 String is immutable. What exactly is the meaning?

要約すると、 文字列変数の値がコード内で変更されていることが確認された場合は、新しいオブジェクトが作成されたとみなすことができます

String s = new String("some value"); 

String s = "some value"; 

非常に同じです。あなたが=を使用すると値が設定されていないが、新しいオブジェクトが実際には同じ参照s

EDITの下に作成された:「Downvoters」については 、答えはYES です。 三つのオブジェクトは

+5

これはどのように多くの文字列が指定されたコードで作成されるのかという質問に関連していますか?また、 '' 'value ''はすでに最初の文の文字列プールに作成されていて、 's'は単に既存の参照に割り当てられています。不変性とは関係ありません。 – RealSkeptic

+1

作成された文字列の数は、それらが不変であるという事実に関連していません。そして、値がすでにプログラムで使用されているリテラルである場合、ステートメント "=' '値は設定されていませんが、新しいオブジェクトが実際に作成されます。 – RealSkeptic

+0

@BrandonIbbotson thatsなぜ私は "文字列を変更して新しいオブジェクトが作成されるのを見るか"という行を付けます。なぜこの答えが完全に誤解を招くのか分かりません – madhairsilence

2
  1. リテラル​​が作成されて作成されます。
  2. ​​と同じ文字列が作成されます。
  3. リテラル"abcKDFghrtjk"が作成されます。

Specification:実行時に連結することによって計算

"This is a string" // a string containing 16 characters 
"This is a " +  // actually a string-valued constant expression, 
    "two-line string" // formed from two string literals 

文字列は、新たに作成され、したがって、別個のものです。
定数式(§15.28)で計算された文字列は、コンパイル時に計算され、リテラルであるかのように処理されます。

4

はい、3です。一見すると、もっと多くのことが考えられますが、コンパイラは文字列定数を組み合わせます。 details in JLS§15.28 - Constant Expressions。ようにコンパイラが効果的にあなたmainの体を扱います。また、クラスの等価定数の同じ文字列(internedなので、同じ文字列が同様に、クラス全体で使用することができます)再利用

String a = new String("abc"); 
String b = "abc"; 
String c = "abcKDFghrtjk"; 

、どのそのコードの​​リテラルの2つの出現によって作成された唯一のものが​​であることを意味します。だから、

  • 一つ​​定数(リテラル)
  • 一つ"abcKDFghrtjk"から他の一定の(いくつかのリテラルを組み合わせた結果)から
  • 一つ​​あなたはで個別のオブジェクトとして明示的に作成コードの最初の行を介してnew String
+0

こんにちはTJさん、「文字列リテラル」だけがコンパイル時の定数として扱われているのでしょうか? – msagala25

+1

@msagala:仕様ごとに一定の値を持つもの。 [詳細はこちら](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28)。それはリテラルであり、['final'文字列変数とフィールドへの参照もあります(https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4) (仕様ではメンバ変数と呼ばれることもあります)。 –

関連する問題