web-dev-qa-db-ja.com

Java:instanceofジェネリック

ジェネリックのクラスタイプを見つける方法はありませんか?

if (T instanceof String) {
    // do something...
}

上記は間違いなくコンパイルされません。

32
someguy

ジェネリックはコンパイル時の機能です。ジェネリックはコンパイル時にチェックを追加しますが、実行時には何の意味もありません。これは一例です。参照されるオブジェクトのタイプのみをチェックできます。これは、コード内のスーパータイプである可能性があります。タイプTを渡したい場合は、明示的にこれを行います。

void someMethod(Class<T> tClass) {
    if(String.class.isAssignableFrom(tClass)) 

または

void someMethod(Class<T> tClass, T tArg) {

注:タイプは同じではない場合がありますが、

someMethod(Number.class, 1);
46
Peter Lawrey

サブクラスがある場合

public class SomeClass extends SomeSubclass<String>{}

そして

public class SomeSubclass<T> {}

次に、コードを実行してTのタイプを発見する方法があります

Type t = getClass().getGenericSuperclass()
if (t instanceof ParameterizedType) {
    Type[] actualTypeArguments = ((ParameterizedType)t).getActualTypeArguments()
    // in simple cases actualTypeArguments will contain Classes, since Class implements Type
}

ケースがもう少し複雑な場合(? extends String) `をご覧ください org.ormunit.entity.AEntityAccessor#extractClass

4
Tomasz Krzyżak

Tは変数ではなく、実行時に定義されるクラスのプレースホルダーであるため、コンパイルされません。以下に簡単なサンプルを示します。

public class Test<T> {

public void something(T arg) {
    if (arg instanceof String) {
        System.out.println("Woot!");
    }
}

public static void main(String[] args) {
    Test<String> t = new Test<String>();
    t.something("Hello");
}

}
3
drekka

特定のフィールドがある場合は、次のように確認できます。

private <T> String someMethod(T genericElement)
{
    if (String.class.isInstance(genericElement))
    {
        return (String) genericElement;
    }
...
1
Adir