web-dev-qa-db-ja.com

オブジェクトがパラメータ型のインスタンスかどうかをテストします

オブジェクトがジェネリック型のインスタンスであるかどうかを判断する方法はありますか?

public <T> test(Object obj) {
    if (obj instanceof T) {
        ...
    }
}

それは明らかに機能しません。代替手段はありますか? Javaリフレクションを使用してクラスをインスタンス化し、それがジェネリックT型であることを確認するようにしたいのと同じように。

70
Nikordaris

このチェックを行う唯一の方法は、タイプを表すClassオブジェクトがある場合です。

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
   //...
}
111
Mark Peters

Mark Petersのサンプルを拡張するには、次のようなことをしたいことがよくあります。

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
   T t = type.cast(obj);
   // ...
}
18
Puce

これを試すことができます、

// Cast your object to the generic type.
T data = null;
try {
    data = (T) obj;
} catch (ClassCastException cce) {
    // Log the error.
}

// Check if the cast completed successfully.
if(data != null) {
    // whatever....
}
5

Mark Petersが述べたように、クラスタイプをパラメーターとして渡したくない場合は、次のコードを使用できます。 David O'Mearaに称賛を。

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                  .getActualTypeArguments()[0];
  if (type.isInstance(obj)) {
      ...
  }
5
Ton Snoei

タイプTClassタイプをパラメーター化するために使用される場所に制限を置く方がより理にかなっています。タイプを渡すとき、Class<?>のようなものを使用する代わりに、Class<? extends T>を使用する必要があります。

3
Chris Dennett

これは、タイプTのオブジェクトがある場合にのみ(部分的に)動作します。その後、そのオブジェクトのクラスを取得できます。Java.lang.Class<T>そして、それが問題のオブジェクトと同じかどうかを調べます。

しかし、これは私たちがジャンルを持っているまさにその理由に反することに注意してください:ジェネリック型を使用することは、それが実際にどの型であるかを気にしないと言う方法です(指定できる上限と下限まで)。

1
Ingo

これも機能します

public <T> void functionName(T input){
    Foo foo = new Foo(); // one of the expected objects
    if(input.getClass().isInstance(foo){
       doSomeThingWith((Foo)input);
    }
}

完全なデモ repl.itでのライブデモ

0
blongho