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

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



福嶋です。

前回の読書会で、項目7の最後に出てくる、

  equals宣言中のObjectを他の型で置き換えてはいけません

ですが、これは、
Frequently Asked Questions (with answers) for programmers using the JavaTM
language
http://pvdl.best.vwh.net/intro.html

のJava Gotcha's
http://java.sun.com/people/linden/faq_d.html#Java%20Gotcha%27s

の6番にある話題
The dynamic type of a method argument doesn't seem to be used to choose
an overridden method at runtime.
と関係しているのか? と思いました。

本の項目7には、

public class MyClass {
  public boolean equals(Object another) {
    if (!(another instanceof MyClass)) {
      return false;
    }
    :
  }
}

みたいにして判定していますが、メソッド引数にもポリモーフィズムを適用して、

public class MyClass {
  public boolean equals(Object another) {
    return false;
  }
  public boolean equals(MyClass another) {
    if (another == null) {
      return false;
    }
    :
  }
}

と書いた方がすっきりするし応用が利くのでは? と思ったりする時があります。

ただし、呼び出すメソッドはコンパイル時に決まってしまうため、

(1)
  MyClass foo = new MyClass();
  MyClass bar = new MyClass();
  boolean fooEqualsBar = foo.equals(bar);

と書けば、MyClass#equals(MyClass)メソッドが呼ばれますが、

(2)
  MyClass foo = new MyClass();
  Object bar = new MyClass();
  boolean fooEqualsBar = foo.equals(bar);

と書くと、barはMyClassオブジェクトのインスタンスですが、型宣言がObject型
であるために、MyClass#equals(Object)メソッドが呼ばれます。
(実行時の型に影響されない)

このことは言語規定(JLS)で定められています。

(2)のパターンでも、MyClass#equals(MyClass)メソッドを呼んで欲しいと思うの
は、私だけでしょうか…?
それとも、今のような仕様になっている理由があるのでしょうか?

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