LoginSignup
0
0

More than 3 years have passed since last update.

Java String の等価演算子(==)と初期化の関係について。初心者向け

Posted at

Java 初心者にとってStringに対して等価演算子(==)の意味が”同じ値かどうか”をみるのではなく、
”参照先が同じかどうか”を見ることだというのは一つの学びのポイントであると思う。

Test1.java
public static void main(String[] args) {
    String str1 = "100";// ⓵
    String str2 = new String("100"); // ⓶
         System.out.println(str1 == str2); //Falseになる。
     }
 }

このときfalseになるのは理解した。でもStringて⓵でも⓶でも初期化できるわけで。
どういうときに参照先が同じになるのか。例えば、以下。

Test2.java
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()メソッドが適用されている。そうすると、メモリ無駄使いもなくなるし。
以下の場合はどうなるんだろう。

Test3.java
 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が特殊なのかを調べるために以下も実行した。

Test4.java
 public static void main(String[] args) {
    Integer int1 = 100;
    Integer int2 = 100;
         System.out.println(str1 == str2);
     }
 }

Trueでした。
てことは参照型の場合において、newを書かない限り、基本的に同じ参照点を見ているといえるのかな。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0