Java 初心者にとってStringに対して等価演算子(==)の意味が”同じ値かどうか”をみるのではなく、
”参照先が同じかどうか”を見ることだというのは一つの学びのポイントであると思う。
public static void main(String[] args) {
String str1 = "100";// ⓵
String str2 = new String("100"); // ⓶
System.out.println(str1 == str2); //Falseになる。
}
}
このときfalseになるのは理解した。でもStringて⓵でも⓶でも初期化できるわけで。
どういうときに参照先が同じになるのか。例えば、以下。
public static void main(String[] args) {
String str1 = "100";
String str2 = "100";
System.out.println(str1 == str2); //Trueになる。
}
}
上の例だとTrueになるのだ。あれ、異なる二つの参照型変数を作ってるからfalseになってしまうのではと思っていた。
等価演算子が”参照先が同じか”を見ているてことなので、このときstr1とstr2は同じ参照先を見ているらしい。
これってどういうことなのかと思っていた。
いろいろぐぐると以下が出てきた。
参考先:String#intern()を使った場合の、パフォーマンスへの影響を学ぶ
要は、Stringにおいて、Intern()メソッドてのがあって、そいつを使うと、同じ文字列のStringオブジェクトがあった場合、
参照先をそろえるみたい。そうするとメモリの無駄使いを減らせる。確かに同じ値なのに、オブジェクトをいちいち作ってるのは効率が悪い。
これが、Test2.javaにおいて起きているのではないか。
つまり、初期化するときには自動的にIntern()メソッドが適用されている。そうすると、メモリ無駄使いもなくなるし。
以下の場合はどうなるんだろう。
public static void main(String[] args) {
String str1 = new String("100");
String str2 = new String("100");
System.out.println(str1 == str2);
}
}
この場合はfalseになるみたい。
てことはnew ~~で初期化するときはIntern()メソッドが適用されずに、newといってるくらいなので、新しくオブジェクトを作っているのだろう。
まとめると、
・str1 = "100", str2 = "100" の場合、参照先が同じになる。
・new String("100")で初期化する場合、新しくオブジェクトを生成するため、参照先は異なる。
ちなみに参照型でこの事象が発生するのか、Stringが特殊なのかを調べるために以下も実行した。
public static void main(String[] args) {
Integer int1 = 100;
Integer int2 = 100;
System.out.println(str1 == str2);
}
}
Trueでした。
てことは参照型の場合において、newを書かない限り、基本的に同じ参照点を見ているといえるのかな。