无法对参数化类型 ArrayList<Foo> 执行 instanceof 检查
Posted
技术标签:
【中文标题】无法对参数化类型 ArrayList<Foo> 执行 instanceof 检查【英文标题】:Cannot perform instanceof check against parameterized type ArrayList<Foo> 【发布时间】:2011-09-07 13:51:39 【问题描述】:以下代码:
((tempVar instanceof ArrayList<Foo>) ? tempVar : null);
原因:
无法针对参数化类型
ArrayList<Foo>
执行instanceof
检查。请改用ArrayList<?>
形式,因为更多的泛型类型信息将在运行时被删除
谁能解释一下“更多的泛型类型信息将在运行时被删除”是什么意思以及如何解决这个问题?
【问题讨论】:
【参考方案1】:这意味着如果你有任何参数化的东西,例如List<Foo> fooList = new ArrayList<Foo>();
,泛型信息将在运行时被删除。相反,这是 JVM 将看到的 List fooList = new ArrayList();
。
这称为type erasure。 JVM在运行时没有List
(示例中)的参数化类型信息。
修复?由于 JVM 在运行时没有参数化类型的信息,因此您无法执行 instanceof
或 ArrayList<Foo>
。您可以显式“存储”参数化类型并在那里进行比较。
【讨论】:
You can "store" the parameterized type explicitly and do a comparison there.
我们可以看看这个例子吗?【参考方案2】:
你总是可以这样做
try
if(obj instanceof ArrayList<?>)
if(((ArrayList<?>)obj).get(0) instanceof MyObject)
// do stuff
catch(NullPointerException e)
e.printStackTrace();
【讨论】:
如果是空的怎么办 @RafaelRuiz 我认为简单的 try/catch 强制转换为正确的类型 ArrayList由于类型擦除,ArrayList
的参数化类型在运行时将是未知的。使用instanceof
可以做的最好的事情是检查tempVar
是否是ArrayList
(任何东西)。要以对泛型友好的方式执行此操作,请使用:
((tempVar instanceof ArrayList<?>) ? tempVar : null);
【讨论】:
【参考方案4】:这就足够了:
if(obj instanceof ArrayList<?>)
if(((ArrayList<?>)obj).get(0) instanceof MyObject)
// do stuff
其实instanceof
检查左操作数是否为null
,如果是null
则返回false
。
所以:没必要抓NullPointerException
。
【讨论】:
这不是更适合对原始帖子发表评论吗? 不需要捕捉NullPointer,但需要捕捉IndexOutOfBounds【参考方案5】:instanceof 运算符在运行时工作。但是 java 在运行时不携带参数化的类型信息。它们在编译时被擦除。因此错误。
【讨论】:
【参考方案6】:你无法解决这个问题。泛型的类型信息在运行时不可用,您将无权访问它。只能查看数组的内容。
【讨论】:
【参考方案7】:你总是可以这样做
创建一个类
public class ListFoo
private List<Foo> theList;
public ListFoo(List<Foo> theList
this.theList = theLista;
public List<Foo> getList()
return theList;
不一样但是...
myList = new ArrayList<Foo>;
.....
Object tempVar = new ListFoo(myList);
....
((tempVar instanceof ListFoo) ? tempVar.getList() : null);
【讨论】:
【参考方案8】:要执行准确的检查类型而不是这样:
protected <Foo> ArrayList<Foo> myMethod(Object tempVar )
return tempVar instanceof ArrayList<Foo>) ? (ArrayList<Foo>) tempVar : null;
你可以这样做:
protected <Foo> ArrayList<Foo> myMethod(Object tempVar, Class<Foo> clz)
if (tempVar instanceof ArrayList && (tempVar.size() == 0 || clz.isInstance(tempVar.get(0))))
return (ArrayList<Foo>) tempVar;
return null;
通过这种方式,您的代码是完全安全的。
【讨论】:
【参考方案9】:你可以使用
boolean isInstanceArrayList = tempVar.getClass() == ArrayList.class
【讨论】:
以上是关于无法对参数化类型 ArrayList<Foo> 执行 instanceof 检查的主要内容,如果未能解决你的问题,请参考以下文章
无法对对象类型 ArrayList 实现 Filterable