Javaの変数における同一性と同値性の違いについて、分かりやすくまとめてみたいと思います。
変数の同一性とは、その変数が同じインスタンスであることを指します。インスタンスを分かりやすく説明するのは難しいですが、クラスを設計図とするならば、インスタンスとはそれぞれ個性を持つ実体の様なものです。クラスのインスタンスを生成するというのは、言い換えれば設計図から実体を作るという意味合いを持ちます。
例えば、下のような変数str1
、str2
がある時、2つの変数は同じインスタンスを共有して参照しています。
1String str1 = "ABC";
2String str2 = str1;
つまり、この2つの変数は同一であると言えます。
付け加えると、Stringクラス
は同じ文字列が代入された場合、同じ参照先が使い回されます。これは参照先が増えるのを防ぐためで、この仕組みをコンスタントプール(Constant Pool)と呼ばれています。
コンスタントプールにより下のような変数str3
、str4
は同じ参照先を参照しているので同一性を持ちます。
1String str3 = "abc";
2String str4 = "abc";
同一性であるかを判定するのには、==演算子
を使います。サンプルコードに同一性を判定するコードを書いてみます。
1public class IdentityTest {
2 public static void main(String[] args) {
3 // str1とstr2が同一であるか判定する
4 String str1 = "ABC";
5 String str2 = str1;
6 System.out.println("str1とstr2の同一性:" + (str1 == str2));
7 // str3とstr4が同一であるか判定する
8 String str3 = "abc";
9 String str4 = "abc";
10 System.out.println("str3とstr4の同一性:" + (str3 == str4));
11 }
12}
実行結果が以下になります。
1str1とstr2の同一性:true
2str3とstr4の同一性:true
str1
とstr2
、str3
とstr4
は同一であることがわかります。
同値性とは、インスタンスが持つ値の内容が同じであることを意味します。
1String str1 = new String("ABC");
2String str2 = new String("ABC");
上のstr1
とstr2
はnew演算子
で異なるインスタンスを生成して、「ABC」を代入しています。値自体はそれぞれ同じ文字列を代入しています。
よって、2つの変数は同一ではないが同値であると言えます。
同値性を判定するには、Objectクラス
のequalsメソッド
を使います。サンプルコードに同値性を判定するコードを書いてみます。
1public class EquivalenceTest {
2 public static void main(String[] args) {
3 String str1 = new String("ABC");
4 String str2 = new String("ABC");
5 // str1とstr2が同一であるか判定する
6 System.out.println("str1とstr2の同一性:" + (str1 == str2));
7 // str1とstr2が同値であるか判定する
8 System.out.println("str1とstr2の同値性:" + str1.equals(str2));
9 }
10}
実行結果が以下になります。
1str1とstr2の同一性:false
2str1とstr2の同値性:true
上の通り、同一性判定はfalse
ですが、同値性判定はtrue
であることが分かります。
上で述べた同一性と同値性の違いについてですが、これらは変数の型が基本データ型ではなく、参照型の場合のみ発生します。
基本データ型は同一性のみ比較される(同一性と同値性が一緒に扱われる)ので、基本データ型で同値性と同値性は違いは発生しません。
変数を比較する場合では、基本データ型では==演算子
、参照型ではequalsメソッド
を使えば良いということです。
今回は同一性と同値性の違いを簡単にまとめました。Java Silverの試験でも問われることが多いトピックなので、アウトプットとして解説してみました。以上で記事を終わりにします。