[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10155] Re: 動的実行メソ ッド決定はなぜされないのか



福嶋です。

On Tue, 28 May 2002 20:50:35 +0900, according to the article
"[jfriends-ml 10147] Re: 動的実行メソッド決定はなぜされないのか"
"TAKAHASHI, Tomohiro" <t_takahashi@xxxxxxxxxxxxxx> wrote:

> > と書くと、barはMyClassオブジェクトのインスタンスですが、型宣言がObject型
> > であるために、MyClass#equals(Object)メソッドが呼ばれます。
> > (実行時の型に影響されない)
> > 
> > このことは言語規定(JLS)で定められています。
> > 
> > (2)のパターンでも、MyClass#equals(MyClass)メソッドを呼んで欲しいと思うの
> > は、私だけでしょうか…?
> > それとも、今のような仕様になっている理由があるのでしょうか?
> snip
> 
>   仮に java.lang.Object の実装が以下のようになっていたら、
> 福嶋さんの望む動作になりませんか?
>   遅そうだけど...
> 
> -------------------------------------------------------------------
> import java.lang.reflect.*;
> 
> public class Object {
>   ...
>   ...
>   public boolean equals(Object that) {
>     try {
>       Class c1 = this.getClass();
>       Method m1 = c1.getMethod("equals", new Class[]{c1});
>       Boolean retval = (Boolean)m1.invoke(this, new Object[]{that});
>       return retval.booleanValue();
>     }
>     catch(Exception e) {
>       return false;
>     }
>   }
>   ...
>   ...
> }

なるほど、リフレクションですか。これは思い付きませんでした。
これだと、Object#equals()がループしてしまいそうなので、まずいですね。
m1がまさにObject#equals(Object)かもしれません。
現在の言語仕様で、instanceofをつかって、本に書かれた契約を満たすように
書くと、以下のような感じでしょうか。

public class MyClass {
  public boolean equals(Object another) {
    if (another instanceof MyClass) {
      return equals((MyClass)another);
    }
    return false;
  }
  public boolean equals(MyClass another) {
    if (another == null) {
      return false;
    }
    
    //具体的なthisとanotherの比較演算
  }
}

----------------------------------------
(株)PFU ソフトプロダクト事業部第二開発部
  福嶋 航  w.fukushima@xxxxxxxxxxxxxxx