Javaコレクションのインターフェイス(たとえば、List
またはSet
)は、任意のオブジェクトを受け入れる方法を定義しています(contains
)。ジェネリック型のチェック
public boolean contains(Object o)
それは、このメソッドを実装するに来るときしかし、私が働いている特定のコレクションは、私はクラスのジェネリック型E
と互換性のあるタイプ(すなわちを持っているいずれかのクラスのEである必要があり、またはEのサブクラス、またはEがインタフェースの場合はEを実装するクラス)。言い換えれば、oがE型にキャスト可能であれば、互換性があります。
public boolean contains(Object o)
{
if(o instanceof E) // compile error due to type erasures
{
// ... check if this collection contains o
}
return false;
}
私の質問は、このような何かを達成するための最良の方法だろうものです:Javaは一般的なタイプの情報を消去するので、このような何かが不可能であるため、これは問題を提示しますか? Oracle Article on Type Erasuresにはこれが禁止されていると記載されていますが、この問題の解決策はありません。
私はこれを回避する一つの半エレガントな方法を考えることができます。キャストが失敗した場合、キャストはE.を入力してください
、oはタイプEやタイプのサブクラスすることはできませんE.
public boolean contains(Object o)
{
try
{
E key = (E) o; // I know it's unsafe, but if o is castable to E then the method should work
// check if this collection contains key
}
catch(ClassCastException e)
{
// invalid type, cannot contain o
}
return false;
}
これはうまくいくものの、見た目が乱雑です(このように例外を使用するのは大したファンではありません)。
この同じ目標(メソッドシグネチャの変更は許可されていません)を実行するより良い方法はありますか?
編集:Eがオブジェクトに消去されますので、ええ、これは動作しません:(
動作しますか?チェックされていないキャストコンパイラ警告が表示されます。 ClassCastExceptionを受け取ることはありません( 'o'は' E'の** erasure **のインスタンスではない(おそらく 'Object'))。 –
"あなたはクラスのジェネリックタイプEと互換性のある型を必要としますか?"ありがとう。 –
私は同意する - これは動作しません。実際のクラスが必要で、失敗する可能性のある適切なキャストを行う必要があります。 –
StaxMan