Stringが他のようにクラスである場合、二重引用符を使用してどのように初期化できますか?
java.lang.String
、Java言語を特別に扱います。
Stringが他のようにクラスである場合、二重引用符を使用してどのように初期化できますか?
java.lang.String
、Java言語を特別に扱います。
回答:
Javaの設計者は、言語のパフォーマンスを向上させるために、すべてをオブジェクトにするのではなく、オブジェクト指向言語でプリミティブ型を保持することにしました。プリミティブはコールスタックに格納され、必要なストレージスペースが少なく、操作が安価です。一方、オブジェクトはプログラムヒープに格納され、複雑なメモリ管理とより多くのストレージスペースが必要になります。
パフォーマンス上の理由から、Javaの文字列はプリミティブとクラスの間にあるように設計されています。
例えば
String s1 = "Hello"; // String literal
String s2 = "Hello"; // String literal
String s3 = s1; // same reference
String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
注: 文字列リテラルは共通のプールに格納されます。これにより、同じ内容の文字列のストレージを共有してストレージを節約できます。String
new演算子を介して割り当てられたオブジェクトはに格納されheap
、同じコンテンツのストレージは共有されません。
JavaはStringを特別なクラスとして扱い、両方の方法で初期化できます
リテラルを直接割り当てる
String a = "adsasdf";
新しいキーワードを使用する他のオブジェクトとして
String a = new String("adsasdf");
==
記号と比較する場合は、特別な注意が必要です。
String a = "asdf";
String b = "asdf";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True
String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b); // False
System.out.println(a.equals(b)); // True
これは、最初のケースでは、オブジェクトaとbは呼び出されたものに保持されliteral pool
、両方が同じオブジェクトを参照しているため、両方の点で等しいためです。
ただし、2番目のケースでは、他のオブジェクトを初期化するときのように、aとbは異なるオブジェクトを参照します。そのため、==
演算子と比較した場合、値は等しくなりますが、等しくありません。
文字列はJLSで特別な扱いを受けます。これは、リテラルが存在する2つの非プリミティブ型の1つです(もう1つはClass
)*です。
JLSから:
文字列リテラルは、 `String [...]クラスのインスタンスへの参照です。
*まあ、「nullリテラル」の「null型」もありますnull
が、ほとんどの人は「null型」を適切な型と考えていません。
null
、任意の参照型変数に任意のものを割り当てることができるようにするための気の利いた表現です。それ以外の場合、これは興味深いタイプではありません。
文字列は、プログラミング言語でよく使用されます。javaはオブジェクト指向であるため、文字列はオブジェクトです。面倒な新しいString( "someString");を回避するには、文字列オブジェクトが必要になるたびに、javaでは、文字列リテラルを使用して文字列オブジェクトを作成できます。
ただし、文字列の等価性に留意する必要があります。ここに私が何を意味するかを示すための短いJUnitテストがあります。
@Test
public void stringTest() {
// a string literal and a string object created
// with the same literal are equal
assertEquals("string", new String("string"));
// two string literals are the same string object
assertSame("string", "string");
// a string literal is not the same object instance
// as a string object created with the same string literal
assertFalse("string" == new String("string"));
// java's String.intern() method gives you the same
// string object reference for all strings that are equal.
assertSame("string", new String("string").intern());
}
new String(String src)
でしか初期化できない場合、コンストラクタに文字列リテラルを与えることさえできません。を初期化してからchar []
、String(char [] src)
コンストラクタを使用して文字列を作成するか、ファイルから文字列を読み取る必要があります。
-文字列内のクラスですジャワ。あなたはそれについて正しいので、いつでもnew
キーワードで初期化できます。
-しかし、次のような場合:
String s = "";
上記のステートメントがでマークされているコンパイラであることを特別なStringオブジェクトとその後、ロード中にJVM(ロードが初期化前に行われる)クラスの、として知られているもの、これを見て、文字列リテラルに格納され、文字列リテラルプール。
-したがって、文字列new()
は""
メソッドを使用して作成できますが、後者は文字列リテラルプールからの参照があるため、文字列オブジェクトへの参照がない場合でもヒープに留まる文字列リテラルを提供します。
Javaは2つのステップからなるプロセスを実行します。
String str = "hello";
に相当
char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);
[.NET] [1]も同様です。
String(Char[]) constructor
する
String(char[] value)
参照の追加:-
"hello"
文字列リテラルであると見、コンパイラによって定数プールに入れられますJLS 3.10.5とJVMS§5.1を。
Java.lang.String
単なるクラスではありません。これはコア言語の不可欠な部分です。コンパイラーはそのための構文糖を持っています。たとえば""
、はの略語のようなものですnew String("")
。書き込まれると""
、コンパイラーは同一のストリングを同じインスタンスに最適化して、スペースを節約します。"a" + 5 == "a5" ==> true
コンパイラーには、オブジェクトバージョンとそのネイティブタイプの間でボックス化/ボックス化解除する必要がないこと、親がオブジェクトを意味しないこと、デフォルトのコンストラクターなど、多くのもののための構文シュガーがあります...
""
はの省略形ではありませんnew String("")
。を使用する""
場合、最初に行われるのは、JVMの文字列プールで一致するものを探すことです。これがtrueの場合、その文字列を返します。を使用new String("")
すると、文字列自体がすでに文字列プールに存在する場合でも、常に新しい文字列が作成されます(文字列プールに格納されないため)。
" "
はすでに文字列です!