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


87

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

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

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

回答:


129

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

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

あなたが取得したくない場合はtype、メソッドのパラメータとして、多分あなたはそれを初期化したい:Class type = ((T) new Object()).getClass();
JordiVilaplana

9
@JordiVilaplanaそれは正しくありません、それはあなたにクラスとしてjava.lang.Objectを与えるでしょう。これをチェックしてください:ideone.com/bxt9Jq
Sri Harsha Chilakapati 2016

3
使用:Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Ton Snoei 2018

22

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

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

11

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

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

5
それは与えType safety: Unchecked cast from Type to Class<T>
マルコ・スッラ

5

あなたはこれを試すことができます、

// 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....
}

7
これは動作しません!キャストはすべてのタイプで成功します。これが、「チェックされていないキャスト」のコンパイル警告を表示する理由です。
Lii 2018

3

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


1
実行時にTの正確なタイプを知りたい場合は、呼び出し元がClass <?ではなくClass <T>を渡すように要求することが重要です。T>を拡張します。たとえば、PuceのコードはClass <?でコンパイルされません。T>を拡張します。
セオドアマードック2014年

1

これは、タイプTのオブジェクトがある場合にのみ(部分的に)機能します。次に、そのオブジェクトのクラスを取得し、java.lang.Class<T>問題のオブジェクトと同じであるかどうかを確認して見つけることができます。

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


null以外のTインスタンスで.getClass()呼び出しから返されたClass <?>は、Class <T>であるとは限りません。保証できる最善の方法は、それがクラスであることです<?T>を拡張します。
セオドアマードック2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.