web-dev-qa-db-ja.com

instanceofがGenericで動作しないのはなぜですか?

可能性のある複製:
Java:InstanceofおよびGenerics

汎用のリストを特定のタイプのリストにキャストする関数を作成しようとしています。以下のコードを見つけます

public <T>List<T> castCollection(List srcList, Class<T> clas){
    List<T> list =new ArrayList<T>();
    for (Object obj : srcList) {
       if(obj instanceof T){
            ...
       }
    }
    return list;
}

だが obj instanceof Tコンパイルエラーを表示-

型パラメーターTに対してinstanceofチェックを実行できません。代わりに、その消去オブジェクトを使用します。>代わりに、さらに一般的な型情報が実行時に消去されるためです。

目的の結果を得るための明確化や方法はありますか?

前もって感謝します。 :)

18

この方法ではできません。幸いなことに、すでに_Class<T>_引数があるので、代わりに

_myClass.isAssignableFrom(obj.getClass())
_

objがクラスmyClassまたはサブクラスの場合、これはtrueを返します。

@ILMTitanが指摘したように(ありがとう)、潜在的なNullPointerExceptionを回避するために_obj == null_を確認するか、代わりにmyClass.isInstance(obj)を使用する必要があります。どちらも必要なことを行います。

37
Jim Garrison

短い答え:Javaの型パラメーターは、型安全性を付与するためにコンパイラーによって使用されるものです。

実行時に、型の消去のためにジェネリック型に関する型情報は破棄されますが、instanceofは実行に具象型(型変数ではない)が必要な実行時チェックです。

8
Jack

Tはパラメーター化された型であり、コンパイルのために存在します。型の消去のため、実行時には存在しません。

したがって、obj instanceof Tは違法です。

4
fge

Javaは消去を使用するため、ジェネリック型を使用してチェックすることはできません。

目的の結果を取得するには、Class.isInstance()を使用します。

4
ILMTitan

ジェネリック型は、コンパイル後に 消去 になり(ジェネリックはコンパイル時の型安全性のためです)、コンパイル後に最も適切な型に置き換えられます。

これをコンパイルする場合は、Tを具象型に置き換えます。例

obj instance String
2
kosa