Eclipse 3.2 のバグ?
Generics を使用した以下のコードがあります。
import java.util.EventObject; public class FooEventextends EventObject { private Class barClazz; public FooEvent(Bar bar) { super (bar); this.barClazz = bar.getClass(); } @Override public Bar getSource() { return barClazz.cast(super.getSource()); } }
このソースですが、Eclipse 3.1 ではコンパイルエラーにならないのですが、Eclipse 3.2 ではエラーになります。
JDK の 1.5 でも試してみたのですが、こちらもコンパイルエラー orz.
コンパイルエラーの内容は以下のとおり。
FooEvent.java:7: 互換性のない型 検出値 : java.lang.Class期待値 : java.lang.Class this.barClazz = bar.getClass(); ^ エラー 1 個
たしかに、Object#getClass() の戻り値は Class なのでコンパイルエラーになるのは正しいのですが、Bar 型のオブジェクトに対する getClass なので、戻り値も Class になって欲しかったです。
実行時の型に左右されてしまうので無理なのかとも思いましたが、変数の型で を導き出してくれればよいので、コンパイラががんばればできる気もします。
まぁ、 barClass.cast(value) と書く事と、(Bar)value と書くこととは、警告の有無だけで実行時の動き*1に差はないと思われるので、素直に (Bar) でキャストしておけって事でしょうかね・・・
そもそも、親クラス(EventObject) で保持される source プロパティの型が Object な時点で、Generics の効力が失われているわけで、もう一度型をつけるには相応のペナルティがあるのは致し方ないわけですが。
#でも、FooEvent のフィールドとして、二重に持つのもイヤですし。
他には、以下の方法もあるけど、イベントクラスで使うにはちょっとと。
public class FooEventextends EventObject { private Class barClazz; public FooEvent(Bar bar, Class barClazz) { super (bar); this.barClazz = barClazz; } @Override public Bar getSource() { return barClazz.cast(super.getSource()); } }
ちなみに、Generics が使われている親クラスに、実装クラスをあらわす Class オブジェクトを渡すのは割と有効な手かも。
おまけ
http://dev.eclipse.org/mhonarc/lists/platform-dev/msg00731.html
http://dev.eclipse.org/mhonarc/lists/platform-dev/msg00733.html
*1:型が合わなければ ClassCastException