4

私はそれを理解することができません

String ab = "hello";        //straight initialization

String ab_1 = new String ("hello_1");  //initializing using new

どちらも機能しますが、

StringBuffer bfr = new StringBuffer("hi");   //works only with new

new で作成された場合にのみ機能します。

String は直接インスタンス化できるのに、StringBuffer には新しい演算子が必要なのはなぜですか。主な理由を教えてください。

4

8 に答える 8

6

すべてのオブジェクトは。でインスタンス化する必要がありますnew。リテラル()からインスタンス化できるのはプリミティブのみint i = 0;です。

唯一の例外は次のとおりです。

  • 特別な初期化構造を可能にする文字列:
   String s = "abc"; //can be instantiated from a literal, like primitives
  • nullインスタンス化:Object o = null;

これは、 Java言語仕様#3.10で定義されています。

リテラルは、プリミティブ型、文字列型、またはnull型の値のソースコード表現です。

注:配列にも専用の初期化パターンがありますが、これはリテラルではありません。

   int[][] a = { { 00, 01 }, { 10, 11 } };
于 2012-08-16T11:32:09.790 に答える
2

使用感String s1 = "hello";String s2 = new String("hello");微妙な違いがあります。

 public static void main(String[] arg ) {
    String s1 = "Java";
    String s2 = "Java";
    String s3 = new String("Java");
    System.out.println(s1==s2); //true
    System.out.println(s1==s3); //false

    StringBuilder sb = new StringBuilder(25); //initial capacikacity
    sb = new StringBuilder(10);
    sb.append(s1).append(" uses immutable strings.");
    sb.setCharAt(20, 'S');
    System.out.println(sb);
}

上記のコードでは、「Java」は文字列リテラルとして知られています。メモリを節約するために、これはコードに表示されますが、どちらも同じ文字列リテラルであるため、s1 と s2 は実際にはメモリ内の同じオブジェクトを参照します。確かs1.equals(s3)にそうですが、上記のようにメモリ内の同じオブジェクトを参照していません。

実際には、常に.equals文字列を比較するために使用しますが、文字列は不変であるため、s1 が参照するデータを変更することはできません (少なくとも簡単ではありません)。しかし、s1 が参照するデータを変更できれば、s2 もそれに伴って変更されます。

StringBuilder を使用すると、基になるデータを変更できます。上記のように、ある String を別の String に追加するためによく使用します。StringBuilder sb2 = "what?"StringBuilders の場合、それらのうちの 2 つが同じデータを参照する (sb1==sb2 を意味する) と、sb1 の変更が sb2 の予期しない変更を引き起こすという問題が発生する可能性が高くなるため、これは違法です。

于 2012-08-16T12:01:49.093 に答える
1
 String ab = "hello";        //straight initialization
 String ac = "hello";  // create one more reference ac

Stringnewキーワードを使用する場合の特殊なケースであり、新しいStringオブジェクトが作成されます。オブジェクトは常にヒープ上にあることに注意してください。文字列プールは、ヒープとは別の独立したメモリ領域ではありません。文字列プールはキャッシュのようなものです。

文字列はJavaで頻繁に使用されるものであり、新しいキーワードを使用して文字列オブジェクトを作成するのはコストがかかるため、JavaがStringPool概念を導入したのもこのようなものです。

同じ値を持つ1つの変数を宣言するacと、javaは新しいobject(String)を作成せずhello、プールにすでに存在する同じobject()を参照するだけです。

 String ab_1 = new String ("hello_1");  //initializing using new

単純にメモリ内にオブジェクトを作成ab_1し、そのオブジェクトを参照します。

于 2012-08-16T11:36:27.433 に答える
1

文字列はJavaの非常に特殊なケースです(これは私の意見ではあまり良いことではありませんが、それは問題ではありません)。

文字列は、他のオブジェクトとは異なり、定数のように直接インスタンス化できます。これを行うと、文字列定数が文字列定数プールに追加され、プリミティブのように処理されます。例を挙げましょう。

String a = "abc";
String b = "abc";

a「プリミティブ」文字列としてインスタンス化すると、プールに追加されます。インスタンス化するbと、同じオブジェクトがプールから返されるため、これを行うと次のようになります。

a == b;

true実際には同じオブジェクトなので、次のようになります。両方をnewでインスタンス化すると、2つの異なるオブジェクトの参照を比較しているため、falseになります(newは別個のオブジェクトの作成を強制します)。

于 2012-08-16T11:36:49.370 に答える
1

「どこに」文字列が「保存される」かに基づいて、もう 1 つの違いがあります。メモリまたは文字列定数プールです。

Java をよりメモリ効率的にするために、JVM は「文字列定数プール」と呼ばれる特別なメモリ領域を確保します。コンパイラは、文字列リテラルを検出すると、プールをチェックして、同一の文字列が既に存在するかどうかを確認します。一致が見つかった場合、新しいリテラルへの参照は既存の String に向けられ、新しい String リテラル オブジェクトは作成されません。(既存の文字列には、参照が追加されているだけです。)

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

この単純なケースでは、「abc」がプールに入り、s がそれを参照します。

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

この場合、new キーワードを使用したため、Java は通常の (非プール) メモリに新しい String オブジェクトを作成し、s がそれを参照します。さらに、リテラル「abc」がプールに配置されます。

于 2012-08-16T11:39:19.253 に答える
1

文字列は、Java コンパイラによって特別に処理されます。などの文字列リテラルを入力する"hello"と、コンパイラは新しいStringオブジェクトを内部的に作成します。

sに対してはそのようなことは実行されませんStringBuffer(ただし、Java はStringBuffers を別の目的 (文字列連結の実装) で内部的に使用します)。

詳細については、文字列オブジェクトと文字列リテラルの違いを参照してください。

その他のヒント:

于 2012-08-16T11:40:44.990 に答える
0

Stringは可変クラスであり、文字列リテラルからStringオブジェクトを作成できる組み込みコンストラクターがあります。

文字列の場合も例外ではありません(プリミティブ.eg int i = 0のように作成するなど)。Stringはまた、コンストラクターを実行して以下を初期化します(違いはその抽象であり、直接表示されません):

String str = "ABC";

ここで「ABC」は、プログラマーが直接使用できない1つのStringオブジェクトも表しますが、Stringプールに存在するためです。そして、このステートメントが実行されると、JVMは内部でプライベートコンストラクターを呼び出し、プールにある「ABC」オブジェクトを使用してオブジェクトを作成します。

于 2012-08-16T11:44:47.393 に答える
0

基本的に、文字列は頻繁に使用されるため、Java は文字列をインスタンス化する簡単な解決策を提供します。

常にこれを使用する代わりに、

String str = new String ("hello");

Java を使用すると、次のことが可能になります。

String str = "hello";
于 2014-02-11T15:12:43.713 に答える