他にもいくつかのSO EclipseのコンパイラでOKをコンパイルするジェネリックについて話しているがjavacではない質問があります(つまり Java:ジェネリックはEclipseとjavacで異なる処理をしました と GenericsはEclipseでコンパイルおよび実行されますが、javac )ではコンパイルされません。ただし、これは少し異なるように見えます。
enum
クラスがあります:
public class LogEvent {
public enum Type {
// ... values here ...
}
...
}
Enum
から派生したタイプの任意のオブジェクトを取り込むメソッドを持つ別のクラスがあります。
@Override public <E extends Enum<E>> void postEvent(
Context context, E code, Object additionalData)
{
if (code instanceof LogEvent.Type)
{
LogEvent.Type scode = (LogEvent.Type)code;
...
これはEclipseで正常に機能しますが、ant
でクリーンビルドを実行すると、1つはinstanceof
行で、もう1つはキャスト行でエラーが発生します。
443: inconvertible types
[javac] found : E
[javac] required: mypackage.LogEvent.Type
[javac] if (code instanceof LogEvent.Type)
[javac] ^
445: inconvertible types
[javac] found : E
[javac] required: com.dekaresearch.tools.espdf.LogEvent.Type
[javac] LogEvent.Type scode = (LogEvent.Type)code;
[javac] ^
なぜこれが発生するのですか?また、正しくコンパイルされるようにこの問題を回避するにはどうすればよいですか?
なぜそれが起こっているのかわかりませんが、回避策は簡単です:
@Override public <E extends Enum<E>> void postEvent(
Context context, E code, Object additionalData)
{
Object tmp = code;
if (tmp instanceof LogEvent.Type)
{
LogEvent.Type scode = (LogEvent.Type)tmp;
...
それは醜いですが、それは機能します...
おそらく、EをEnum <E>を拡張するものとして宣言したためです。完全に理解しているとは言えませんが、タイプのセットが何らかの理由でLogEvent.Typeを含めることができないサブセットに制限されているようです。あるいは、コンパイラのバグかもしれません。誰かがそれをより明確に説明できれば幸いですが、あなたができることは次のとおりです。
public <E extends Enum<?>> void postEvent(E code)
{
if (code instanceof LogEvent.Type)
{
LogEvent.Type scode = (LogEvent.Type)code;
...
}
...
これは機能し、オブジェクトにキャストするよりもエレガントです。
同様の問題が発生し、jdk1.6.0_16からjdk1.6.0_23にアップグレードしたところ、コードを変更せずに解消されました。
instanceof
を使用するには、両方のオペランドが同じクラス/インターフェースを継承/実装する必要があります。
EをLogEvent.Typeにキャストすることはできません
あなたの完全な方法がどのように見えるかはわかりませんが、これはジェネリックではなくインターフェースを使用することで問題を解決するはずです。
public interface EventType { }
public class LogEvent {
public enum Type implements EventType {}
}
public void postEvent(Context context, EventType code, Object additionalData) {
if(code instanceof LogEvent.Type) {
}
}