今回はJavaの変数における同一性と同値性の違いについてまとめます。
同一性と同値性については、Javasilverの試験で問われることが多いトピックです。
同一性とは
同一性とは、同じインスタンスであることを指します。(インスタンスとは分かりやすく説明するのは難しいですが、それぞれ個性を持つ個体の様なものです)
例えば、
String str1 = "ABC"; String str2 = str1;
のような変数str1,str2がある時、2つの変数は同じインスタンスを共有して参照しています。
つまり、2つの変数は同一であると言えます。
付け加えると、Stringクラスは同じ文字列が代入された場合、同じ参照先が使われます。(参照先が増えるのを防ぐためで、コンスタントプールと呼ばれています)
String str3 = "abc"; String str4 = "abc";
str3とstr4は同じ参照先を参照しているので同一性を持ちます。
同一性であるかを判定するのには、「==演算子」を使います。サンプルコードに同一性を判定するコードを書いてみます。
サンプルコードと出力結果
public class IdentityTest { public static void main(String[] args) { // str1とstr2が同一であるか判定する String str1 = "ABC"; String str2 = str1; System.out.println(str1 == str2); // str3とstr4が同一であるか判定する String str3 = "abc"; String str4 = "abc"; System.out.println(str3 == str4); } }
true true
str1とstr2、str3とstr4は同一であることがわかります。
同値性とは
同値性とは、異なるインスタンスを参照しているが同じ値を持っていることです。
String str1 = new String("ABC"); String str2 = new String("ABC");
上のstr1とstr2はnew演算子で異なるインスタンスを生成して、「ABC」を代入しています。値自体はそれぞれ同じ文字列を代入しています。
よって2つの変数は同一ではないが同値であると言えます。
同値性を判定するには、Objectクラスのequalsメソッドを使います。サンプルコードに同値性を判定するコードを書きます。
サンプルコードと出力結果
public class equivalenceTest { public static void main(String[] args) { // str1とstr2が同一であるか判定する String str1 = new String("ABC"); String str2 = new String("ABC"); System.out.println(str1 == str2); // str1とstr2が同値であるか判定する System.out.println(str1.equals(str2)); } }
false true
上の通り、同一性判定はfalseですが、同値性判定はtrueであることが分かります。
同一性と同値性の違いは参照型でのみ発生する
上で述べた同一性と同値性の違いについてですが、これらは基本データ型ではなく、参照型の場合のみ発生します。
基本データ型は同一性のみ比較される(同一性と同値性が一緒に扱われる)ので、基本データ型で同値性と同値性は違いは発生しません。
つまり、変数を比較する場合では
- 基本データ型では「==演算子」
- 参照型では「equalsメソッド」
を使えば良いということです。
まとめ
今回やったことのまとめです。
- 同一性は同じインスタンス、同値性は異なるインスタンスで同じ値が入っている
- 同一性は「==演算子」で判定する
- 同値性はequalsメソッドで判定する
以上が同一性と同値性の違いになります。