web-dev-qa-db-ja.com

文字列に新しいキーワードが不要な理由

私はJavaが初めてです。

Javaでは、Stringclassです。ただし、クラスnewのオブジェクトを作成するためにStringキーワードを使用する必要はありません。ここで、newは、他のクラスのオブジェクトを作成するために使用されます。

IntegerDoubleのようなこれに似たラッパークラスについて聞いたことがあります。しかし、Stringはラッパーではありませんか?

実際に使用すると何が起こっているのか

     String message = "Hai";

??との違い

String message = new String("Hai");

これがmessage参照変数か何か他のものですか?オブジェクトを作成するためにnewを必要としない他のクラスはありますか?

33
sonu thomas

次の行では、ヒープ内に新しいStringオブジェクトを作成するのではなく、文字列リテラルを再利用しています(すでに使用可能な場合)。

_String message = "Hai";
_

_"Hai"_は、文字列リテラルプール内の文字列リテラルです。文字列は不変であるため、再利用可能であり、JVMによって文字列リテラルプールにプールされます。そして、これはあなたがそれを再利用しているので、推奨される方法です。

ただし、以下を使用すると、実際には(ヒープ内に)新しいオブジェクトが作成されます。

_String message = new String("Hai");
_

new String("Hai")は新しいStringオブジェクトです。この場合、リテラル_"Hai"_がすでに文字列リテラルプールにあったとしても、新しいオブジェクトが作成されます。同じ値を持つ複数のStringオブジェクトで終わる可能性があるため、これはお勧めしません。

この投稿も参照してください: Javaの文字列プールに関する質問

オブジェクトを作成するためにnewを必要としない他のクラスはありますか?

実際には、キーワードnewを使用せずに、Javaでオブジェクトを作成することはできません。

例えば.

_Integer i = 1;
_

Integerオブジェクトがnewを使用せずに作成されるという意味ではありません。 newキーワードを明示的に使用する必要はありません。ただし、内部的には、値1のIntegerオブジェクトがまだキャッシュに存在しない場合(IntegerオブジェクトはJVMによってキャッシュされます)、newキーワードを使用して作成します。 。

24
Bhesh Gurung

Java言語仕様では、文字列をリテラルとして表現できます。これは、異なる1つの重要な副作用がある文字列のショートカット初期化と見なすことができます。通常の初期化からnew

文字列リテラルはすべてinternedです。これは、Javaランタイムによって格納される定数値であり、複数のクラス間で共有できることを意味します。例:

class MainClass (
    public String test = "hello";
}

class OtherClass {
   public String another = "hello";

   public OtherClass() {
       MainClass main = new MainClass();
       System.out.println(main.test == another);
   }
}

両方のStringインスタンスが実際には同じオブジェクトを指しているため、「true」が出力されます。 newキーワードを使用して文字列を初期化する場合、これは当てはまりません。

8
Perception

文字列と整数の作成は異なります。

String s = "Test";

ここで、「=」演算子は文字列に対してオーバーロードされています。 「some」+「things」の「+」演算子も同様です。どこで、

Integer i = 2;

Java 5.0まではコンパイル時エラーです。ラッパーにプリミティブを割り当てることはできません。しかしJava 5.0からは、プリミティブが自動プロモートされる自動ボクシングと呼ばれます。必要に応じてラッパーに。

String h1 = "hi";

とは異なります

String h2 = new String("hi");

その理由は、JVMがすべての文字列リテラルの文字列テーブルを維持しているためです。したがって、テーブルに「hi」のエントリがあり、アドレスが1000であるとします。

ただし、文字列オブジェクトを明示的に作成すると、アドレスが2000であるなど、新しいオブジェクトが作成されます。新しいオブジェクトは、文字列テーブルのエントリである1000を指します。

したがって、あなたが言うとき

h1 == h2

比較します

1000 == 2000

だからそれは間違っています

7
Pragalathan M

Javaの場合
"=="は、左側と右側のメモリ位置を比較します(そのメモリ位置の値ではありません)。したがって、

new String("hai")==new String("hai")

falseを返します。

"Hai" == "Hai"の場合、Javaは同じ文字列リテラルに個別のメモリを割り当てないため、ここで "=="はtrueを返します。equalsメソッドを使用して値を比較できます。 。

1
vkantiya