2011-04-20 75 views
51

有没有方法可以确定对象是否是泛型类型的实例?测试对象是否为instanceof参数类型

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

这显然不起作用。有其他选择吗?就像我想使用Java反射来实例化一个类,然后检查以确保它是通用类型T

回答

80

,你可以做这种检查的唯一方法是,如果你有代表型的Class对象:

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

如果你不想把'type'作为方法参数,也许你想初始化它:'Class type =((T)new Object())。'getClass();' – JordiVilaplana 2016-01-14 00:18:12

+4

@JordiVilaplana这是不对的它会给你java.lang.Object作为类。检查此:http://ideone.com/bxt9Jq – 2016-04-13 08:55:58

+0

用途:'类类型=(类)((ParameterizedType)getClass()。getGenericSuperclass())。getActualTypeArguments()[0];' – 2018-02-02 07:58:29

3

将类型用于参数化Class类型的限制将会更有意义。当你输入类型时,不要使用类似Class<?>的东西,你应该使用Class<? extends T>

+1

如果你想知道在运行时的确切类型T的,它要求调用者传递一个类是很重要的,而不是一个类。例如,Puce的代码不能用类进行编译。 – 2014-05-21 20:38:03

1

这只会工作(部分),如果你有一个类型T的对象,然后就可以得到该对象的类,请参阅java.lang.Class<T>并查找它是否与所讨论的对象相同。

但是请注意,这与我们有genrics的原因相反:使用泛型类型是一种说法,您并不在乎它的真实类型(可以指定的上限和下限)。

+0

该类从非null T实例上的.getClass()调用返回时不保证是类。最好的保证是它是一个类。 – 2014-05-21 20:43:29

12

延长马克·彼得斯的样品,经常要像做:

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

你可以试试这个,

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

**这不起作用!**对于所有**类型,演员成功。这就是为什么它会给出“未经检查的强制转换”编译警告。 – Lii 2018-02-02 08:47:44

1

如果你不想通过类类型Mark Peters提到的一个参数,你可以使用下面的代码。荣誉David O'Meara。

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