检查通用实例?

时间:2011-09-08 16:09:39

标签: java oop

您好我有一个方法应根据类型返回不同的结果。

我可以这样做来检查通用类型。

public <T> T search(final String query){
 T returnValue = null;
 if (returnValue instanceof String){ }
 if (returnValue instanceof Integer){ }
 if (returnValue instanceof MyObject){ }

但为什么我不能这样做?

public <T> T search(final String query){
 T returnValue = null;
 if (T instanceof String){ }
 if (T instanceof Integer){ }
 if (T instanceof MyObject){ }

致电代码。

String id = myObjcet.<String> search("select ...");

3 个答案:

答案 0 :(得分:4)

Java通过“擦除”实现泛型。这意味着在运行时(根本)根本不了解泛型。相反,编译器检查泛型,但在封面下它将所有内容转换为Object(或最近的泛型边界)。

如果使用javap反编译该方法,您会看到它显示为:

public Object search(...

删除对T的每个引用。

这是Java中泛型的一个严重限制,通常也会在JRE类中反映出如下构造:

SomeClass<String> x = new SomeClass<String>(String.class);

需要第三次重复String(String.class),因为构造函数需要知道它在哪个类上运行。

这种范例尽管很可怕,但可以解决你的问题。

有关泛型的信息实际上包含在.class文件中,作为元数据,可以使用反射检查它们,并且在某种程度上也可以解析。但是,在像您这样的情况下,这是不可能的,但它是由ORM在列表获取器上使用的。例如,使用Hibernate,这样的getter:

public List<Group> getGroups() {

可以通过Hibernate进行检查,以便它知道该列表应该包含Group的实例,并相应地调整其查询。

(但是,即使没有以这种方式实现的泛型,T不是实例,它也是一个类,编写String instanceof String同样错误。它应该是if(T.equals(String.class)))< / p>

答案 1 :(得分:1)

因为T在运行时被删除。它只在编译时出现。 returnValue是变量 - 它在运行时出现。

答案 2 :(得分:1)

public <T> T search(Class<T> clazz, String query){
 T returnValue = null;
 if (clazz==String.class){ }
 if (clazz==Integer.class){ }
 if (MyObject.clazz.isAssignableFrom(clazz){ }


String id = myObjcet.search(String.class, "select ...");