进行比较时,出现“ instanceof的非法通用类型”错误

时间:2018-11-19 07:28:42

标签: java android

在我的代码中,有3个自定义类

CheckinTemplate
Employee
Status

尽管有一种情况可能是Object o,但可能是以上类别的任何列表。我想进行如下比较并执行某些逻辑,但出现错误“ instanceof的非法泛型”

if (o instanceof List<CheckinTemplate>) {

} else if (o instanceof List<Employee>) {

} else if (o instanceof List<Status>) {

}

4 个答案:

答案 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.7. Reifiable Types

  

...

     

只有当以下条件之一成立时,类型才是可更改的:

     
      
  • 它是指非通用类或接口类型声明
  •   
  • 这是一个参数化类型,其中所有类型参数都是无界通配符
  •   
  • 这是原始类型
  •   
  • ...
  •   

这是可以理解的,因为有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) {
}