==演算子が参照の比較に使用されているため、以下のコードは「Bye」を出力しませんが、奇妙なことに「Bye」が出力されます。なぜこれが起こるのですか?IDEとしてNetbeans 6.9.1を使用しています。
public class Test {
public static void main(String [] args) {
String test ="Hi";
if(test=="Hi"){
System.out.println("Bye");
}
}
}
この動作はインターンが原因です。動作はのドキュメントに記載されString#intern
ています(呼び出したことがないのにコードに表示される理由を含むString#intern
):
文字列のプールは、最初は空で、クラスによってプライベートに維持され
String
ます。
intern
メソッドが呼び出されたときに、メソッドString
によって決定されたこのオブジェクトに等しい文字列がプールに既に含まれている場合、プールequals(Object)
からの文字列が返されます。それ以外の場合、このString
オブジェクトはプールに追加され、このオブジェクトへの参照String
が返されます。これは、任意の二つの文字列のためにそれを次の
s
とt
、s.intern() == t.intern()
あるtrue
場合にのみs.equals(t)
当てはまります。すべてのリテラル文字列と文字列値の定数式がインターンされます。文字列リテラルは、Java言語仕様の §3.10.5で定義されています。
だから例えば:
public class Test {
private String s1 = "Hi";
public static void main(String [] args) {
new Test().test();
System.exit(0);
}
public void test() {
String s2 ="Hi";
String s3;
System.out.println("[statics] s2 == s1? " + (s2 == s1));
s3 = "H" + part2();
System.out.println("[before interning] s3 == s1? " + (s3 == s1));
s3 = s3.intern();
System.out.println("[after interning] s3 == s1? " + (s3 == s1));
System.exit(0);
}
protected String part2() {
return "i";
}
}
出力:
[静力学] s2 == s1?true [インターン前] s3 == s1?false [インターン後] s3 == s1?本当
それを歩く:
s1
は自動的にインターンされるため、最終的にs1
プール内の文字列を参照します。s2
も自動的にインターンされるため、最終的s2
には同じインスタンスがs1
ポイントするようになります。JavaのString
インスタンスは不変であるため、2ビットのコードが互いに完全に認識されていない場合でも、これは問題ありません。それらを変更することはできません。などのメソッドを使用して、変更toLowerCase
後の新しい文字列を取得できますが、呼び出した元の文字列toLowerCase
などは変更されません。したがって、それらは無関係のコード間で安全に共有できます。String
インスタンスを作成します。新しいインスタンスには、インターンされたインスタンスと同じ文字シーケンスがありますが、別のインスタンスです。ランタイムは、動的に作成された文字列を自動的にインターンしません。これは、コストがかかるためです。プールで文字列を見つける作業。(コンパイルする場合、コンパイラはそれ自体にその費用を取ることができます。一方)だから今、私たちは2つのインスタンス、1持っているs1
とs2
の点に、そして1つのs3
にポイントを。したがって、コードはそれを示していs3 != s1
ます。s3
ます。おそらくこれは、長い間保持する予定の大きな文字列であり、他の場所で複製される可能性が高いと考えられます。したがって、メモリ節約の見返りとして、インターンする作業を受け入れます。定義による解釈とは、新しい参照を取得できることを意味するため、結果をに割り当てs3
ます。s3
同じインスタンスs1
をs2
ポイントしてポイントしていることがわかります。この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加