您好我有一个方法应根据类型返回不同的结果。
我可以这样做来检查通用类型。
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 ...");
答案 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 ...");