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

[jfriends-ml 12146] Re: Generics と Interface で ( 別に パズルという訳ではないのですが ...)



門脇です。

意外にもコンパイルが通るんですね....

At Fri, 18 Nov 2005 14:55:46 +0900,
"TAKAHASHI, Tomohiro" <t_takahashi@xxxxxxxxxxxxxx> wrote:

> interface InfA<T> {
>   public void setData(T x);
> }
> 
> interface InfB<T> {
>   public void setData(T x);
> }

この InfA と InfB は共に同じ erasure になる、と。

taro@iroha:~/workspace3.1/test/src$ javap test.InfA
Compiled from "Test.java"
interface test.InfA{
    public abstract void setData(java.lang.Object);
}

taro@iroha:~/workspace3.1/test/src$ javap test.InfB
Compiled from "Test.java"
interface test.InfB{
    public abstract void setData(java.lang.Object);
}

で、この public abstract void setData(java.lang.Object); を 
Untitled1 が実装しているから、コンパイル可能、実行可能、なんです
ね。
でもジェネリック化されたインターフェイスをパラメータ化せずに実装
できる、というのは、なんと言うか直感に反する気がします。


> public class Untitled1 implements InfA, InfB {
.... 略 ....
>   public static void main(String[] args) {
>     Untitled1 obj = new Untitled1();
>     InfA<String> a = obj;
>     String test = "test";
>     a.setData(test);
>   }
> }

おまけに、この場合だと

obj.setData("test"); // setData(String) を呼ぶ

と

a.setData("test"); // setData(Object) を呼ぶ

では結果が異なるんですね。
InfA (or InfB) 経由だと、setData(Object) が呼ばれる、と。落ち着
いて考えれば当然といえば当然ですけど、ぱっと見、分かりにくいです
ね。さらに

((InfA) obj).setData("test"); // setData(Object) を呼ぶ
((InfB<String>) obj).setData("test"); // setData(Object) を呼ぶ
((InfB<Integer>) obj).setData(1); // setData(Object) を呼ぶ

なのに、

((InfA<Integer>) obj).setData("test"); // setData(Object) を...呼べない

はコンパイルエラーになる、と。;-)


> Yasuhiro Endoh wrote:
> > 
> > 遠藤です。
> > 
> > 今読んでいる本のP8の下から3行目
> > [制約6] イレイジャ処理の結果、メソッドのシグニチャが同じになるメソッドは定義できない
> > にあたるところではないでしょうか。
> > 
> > より正確にはP37の
> > メソッドがオーバーロードされるのは、
> > 名前が同じで、オーバーライド等価ではないシグニチャを
> > 持つ場合だけです。
> > かと。

これは JLS 3rd だと 227 ページあたりでしょうかね。
-- 
門脇 太郎#奥が深い