スポンサード リンク

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スポンサード リンク
-- : -- : -- | スポンサー広告 | page top↑
スポンサード リンク

Javaにおけるequals()メソッドの実装

以前作成したJavaの複素数クラスComplexを題材として、equals()メソッドの実装について論じます。

下のプログラムは典型的な?誤りの例です。一見正しそうに見えるかもしれませんが、このプログラムには問題があります。

誤った例

public boolean equals(Complex c) {
	if (re == c.re && im == c.im)
		return true;
	else
		return false;
}

確かに、Complexクラス同士を比較するのがわかっているのであれば、引数にComplex型の参照を取ればよいと思うかもしれません。

しかし、スーパークラスであるObjectでequals()メソッドはpublic boolean equals(Object obj)と定義されているため、引数の型をComplexにかえてしまうと、メソッドのオーバーライド(再定義)ではなくオーバーロード(多重定義)になってしまいます。

そのため、この実装では次のプログラムが想定外の動きをします。

public static void main(String args[]) {
	Set s = new HashSet();
	Complex c1 = new Complex(1, 2);
	Complex c2 = new Complex(1, 2);
	
	s.add(c1);
	if(s.contains(c1))
		System.out.println("contains c1.");
	else
		System.out.println("doesn't contains c1.");
	if(s.contains(c2))
		System.out.println("contains c2.");
	else
		System.out.println("doesn't contains c2.");
}

実行結果

contains c1.
doesn't contains c2.

contains()が内部処理でequals(Object obj)を呼び出しており、オーバーロードしたequals(Complex c)は無視されています。Objectクラスのequals()は参照の同一性(つまり、物理的な同一性)でもってtrueかfalseを返しているため、このような結果になります。確かに、c1しかadd()していませんが、c1とc2は論理的には同じ値ですので、contains c2でもあって欲しいです。

次の例は先程の問題点(+α)を修正したプログラムです。今度こそ良さそうに思えるかもしれませんが、これでも不十分です。

不十分な例

public boolean equals(Object obj) {
	Complex c = (Complex) obj;
	if (re == c.re && im == c.im)
		return true;
	else
		return false;
}

理由を書くと長くなるので、興味のある方にはEffective Javaを読んでいただくとして、ここではEclipseによって生成されたequals()メソッドのコードを示しておきます。

Effective Java プログラミング言語ガイドEffective Java プログラミング言語ガイド
Joshua Bloch

ピアソン・エデュケーション 2001-12-03
売り上げランキング : 50875
おすすめ平均

Amazonで詳しく見る
by G-Tools

Eclipseによって生成されたコード

public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	final Complex other = (Complex) obj;
	if (Double.doubleToLongBits(im)
	    != Double.doubleToLongBits(other.im))
		return false;
	if (Double.doubleToLongBits(re)
	    != Double.doubleToLongBits(other.re))
		return false;
	return true;
}

関連記事


スポンサード リンク

テーマ:プログラミング - ジャンル:コンピュータ - ソーシャルブックマーク: この記事をクリップ! Yahoo!ブックマークに登録

00 : 00 : 00 | プログラミング-Java | トラックバック(0) | コメント(0) | page top↑
<<EclipseによるhashCode()およびequals()の生成 | ホーム | 演算子のオーバーロードを使用した複素数クラスComplex(C#による実装)>>
コメント

コメントの投稿














管理者にだけ表示を許可する

トラックバック
トラックバックURL
http://networkprogramming.blog18.fc2.com/tb.php/80-2a614da5
この記事にトラックバックする(FC2ブログユーザー)
| ホーム |

プロフィール

TBVector

Author:TBVector

プロフィール

メールフォーム

記事検索

Google

最近の記事

人気の記事

過去の記事

カテゴリー

タグランキング

リンク

最近のコメント

最近のトラックバック

アクセスカウンタ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。