在我的代码中,有3个自定义类
CheckinTemplate
Employee
Status
尽管有一种情况可能是Object o
,但可能是以上类别的任何列表。我想进行如下比较并执行某些逻辑,但出现错误“ instanceof的非法泛型”
if (o instanceof List<CheckinTemplate>) {
} else if (o instanceof List<Employee>) {
} else if (o instanceof List<Status>) {
}
答案 0 :(得分:5)
这无法完成,因为instanceof
是在运行时评估的,但是泛型类型参数在编译过程中会被删除。这意味着在运行时List<CheckinTemplate>
和List<Employee>
之间没有区别。
您可以检查是否为o instanceof List
(如果要避免使用原始的o instanceof List<?>
类型,请检查List
)。如果是,则可以将其强制转换为List
(或List<?>
),然后对其元素运行instanceof
以确定其类型。
if (o instanceof List) {
List list = (List) o;
for (Object e : list) {
if (e instanceof CheckinTemplate) {
} else if (e instanceof Employee) {
} else if (e instanceof Status) {
}
}
}
答案 1 :(得分:0)
有两种方法可以检查对象的类名并将其与字符串进行比较
if(o.getClass.toString().equals("myClass")){
}
第二秒您可以检查此类的实例!
if (object instanceof MyClass) {
}
您在尝试做什么(o instanceof List<CheckinTemplate>
错了,如果在if条件下,则像array.get(x)
或object instanceof CheckinTemplate
一样!
答案 2 :(得分:0)
Java语言规范规定:
15.20.2. Type Comparison Operator instanceof:
如果在instanceof运算符后面提到的ReferenceType不表示可引用的引用类型(第4.7节),则是编译时错误。
...
只有当以下条件之一成立时,类型才是可更改的:
- 它是指非通用类或接口类型声明
- 这是一个参数化类型,其中所有类型参数都是无界通配符
- 这是原始类型
- ...
这是可以理解的,因为有4.6. Type Erasure,也就是说,在编译时类型信息丢失了,并且没有放入已编译的类文件中。在运行时,虚拟机没有可用的类型信息来检查列表是什么类型,因此instanceof
无法对其进行检查。
答案 3 :(得分:0)
您不能在instanceof
中使用通用类型,即可以执行o instanceof List
,但不能执行o instanceof List<Status>
。这是因为Java在编译时会删除泛型类型信息。
当然,您可以使用一种技巧。如果您确定列表是非空且同质的(列表中的所有项目都是同一类型,而不是null),那么请检查列表类型之一,而不是检查列表类型。
Object item = o.get(0);
if (item instanceof CheckinTemplate) {
} else if (item instanceof Employee) {
} else if (item instanceof Status) {
}