こんにちは,ツジです.
今回はJavaのラッパークラスの特殊な仕様についてちょっと紹介しようかなと思います.
同値性と同一性について
特殊な仕様について紹介するにあたり,その前に同値性と同一性について知っておく必要があるので簡単に説明させてもらいます.
同一性とは
同一性は,オブジェクトがメモリ上で同じインスタンスを参照しているかという点で判定を行うために使用されます.
すごく簡単に言うと,そのオブジェクトがメモリ上に同じ場所にあるのかということですね.
で,Javaのラッパークラスにおける関係演算子 “==” 演算子はこの同一性を判定するためのものとなっています.
実際にコードに書き起こして確認してみると,こんな形ですね.
Integer num1 = 1000;
Integer num2 = 1000;
System.out.printf("%b", num1==num1); // true
System.out.printf("%b", num1==num2); // false
「メモリの位置が同じ場所なのか」という点を見ているので,例え値が同様のものであっても後者は “false” が出力される結果となっています.
同値性とは
同値性は,オブジェクトが論理的に同じ値を持っているかという点で判定を行うために使用されます.
これについてはお馴染みのものかと思います.
で,Javaのラッパークラスにおいて同値性を判定するには主に “equals()” メソッドが使用されます.
また,実際にコードで書き起こして確認してみましょう.
Integer num1 = 1000;
Integer num2 = 1000;
System.out.printf("%b", num1.equals(num1)); // true
System.out.printf("%b", num1.equals(num2)); // true
今回は,「論理的に同じ値なのか」という部分をみているのでどちらも”true”という結果が得られましたね.
ラッパークラスにおける特殊な仕様について
同一性と同値性については簡単にですが理解できましたでしょうか.
では,ここでもう一度おさらいをしてみましょうか.
次のコードにおける出力はどのような結果になると思いますか?
Integer num1 = 25;
Integer num2 = 25;
System.out.printf("%b", num1==num2);
「”==”演算子で同一性を判定しているから”false”」だと思いますよね?
しかし,出力は”true”という結果が得られると思います.
これがJavaのラッパークラス(今回は”Integer”を例としてあげましたが)の特殊?な仕様となっています
Integerクラスにおいて,異なるオブジェクトでも”==”演算子で”true”となる値は「-128〜127」となっています.
実際にIntegerクラスのソースコードを確認してもらえればより詳しく分かると思いますが,
Integerクラスにおいて「-128〜127」の値については「ここのメモリに用意しているよ(キャッシュテーブル)」という記述がされています.
これは他のラッパークラス「Character」や「Double」でも同様の仕様が用意されていたはずです.
もっと詳しく知りたい方は,Javaのソースコードを読んだり「オートボクシング」といったキーワードで調べてみてください.
値を比較するのであれば,比較演算子を使うべきではない?
「”==”演算子は同一性をみるためのものだから,じゃあ値を比較したい時は絶対に”equals()”メソッドを使おう」という考えになるかもしれませんが,ちょっと待ってください.
確かにラッパークラスにおいてはそれで良いかもしれません.ラッパークラスにおいては.
Javaには変数型として,プリミティブ型も用意されていますよね?
このプリミティブ型における同値性判定は,”==”演算子を使用するので,安易に「Javaにおける”==”演算子は同一性をみるためのものだ!」という考えは少し危ないので注意してください.
さいごに
どうでしたか?
Javaの同一性と同値性の仕様について少し理解することはできたでしょうか.
個人的にこの仕様を知った時に自分は「面白いとみるか,意味がわからないと取るかで意見が分かれそうだなぁ〜」と思いました.
普段使ってる言語でも,ちょっと変わった?仕様が組み込まれていたりするので,たまに気分転換に今使っているその言語についてもっと調べてみても面白いかもしれないですね.
今回もここまで読んでいただきありがとうございました!
また次回の記事をお楽しみに