オブジェクトがジェネリック型のインスタンスであるかどうかを判断する方法はありますか?
public <T> test(Object obj) {
if (obj instanceof T) {
...
}
}
それは明らかに機能しません。代替手段はありますか? Javaリフレクションを使用してクラスをインスタンス化し、それがジェネリックT
型であることを確認するようにしたいのと同じように。
このチェックを行う唯一の方法は、タイプを表すClass
オブジェクトがある場合です。
Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
//...
}
Mark Petersのサンプルを拡張するには、次のようなことをしたいことがよくあります。
Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
T t = type.cast(obj);
// ...
}
これを試すことができます、
// 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....
}
Mark Petersが述べたように、クラスタイプをパラメーターとして渡したくない場合は、次のコードを使用できます。 David O'Mearaに称賛を。
Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
if (type.isInstance(obj)) {
...
}
タイプT
がClass
タイプをパラメーター化するために使用される場所に制限を置く方がより理にかなっています。タイプを渡すとき、Class<?>
のようなものを使用する代わりに、Class<? extends T>
を使用する必要があります。
これは、タイプTのオブジェクトがある場合にのみ(部分的に)動作します。その後、そのオブジェクトのクラスを取得できます。Java.lang.Class<T>
そして、それが問題のオブジェクトと同じかどうかを調べます。
しかし、これは私たちがジャンルを持っているまさにその理由に反することに注意してください:ジェネリック型を使用することは、それが実際にどの型であるかを気にしないと言う方法です(指定できる上限と下限まで)。
これも機能します
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でのライブデモ