为什么这个涉及泛型的编译时出现错误?

时间:2014-10-13 20:36:29

标签: java generics

以下2个课程详述如下:

class Gen<T> {
    T ob;

    Gen(T o) {
       ob = o;
    }

    // Return ob.
    T getob() {
         return ob;
    }
}

class Gen2<T> extends Gen<T> {
    Gen2(T o) {
        super(o);
    }
}

class HierDemo3 {
    public static void main(String args[]) {

         // Create a Gen2 object for Integers.
         Gen2<Integer> iOb2 = new Gen2<Integer>(99);

         if(iOb2 instanceof Gen2<Integer>) //compile-time error
                System.out.println("iOb2 is instance of Gen2<Integer>");
    }
 }

我非常清楚它会编译:

     iOb2 instanceof Gen2<?>

听起来在运行时没有可用的泛型类型信息。如果是的话,什么时候可用?我很困惑......

1 个答案:

答案 0 :(得分:3)

在编译结束时,会出现type erasure,并且生成的字节码中不存在此类型信息。发生这种情况是因为Java需要保持与泛型前编写的代码的向后兼容性。 JVM没有泛型的概念。

  

泛型被引入到Java语言中,以便在编译时提供更严格的类型检查并支持泛型编程。为了实现泛型,Java编译器将类型擦除应用于:

     
      
  • 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或对象。因此,生成的字节码只包含普通的类,接口和方法。
  •   
  • 如有必要,插入类型转换以保护类型安全。
  •   
  • 生成桥接方法以保留扩展泛型类型中的多态性。   类型擦除确保不为参数化类型创建新类;因此,泛型不会产生运行时开销。
  •   

instanceof运算符本质上是一个运行时操作,因此它无法确定泛型类型参数是什么,因此编译器必须禁止instanceof的泛型类型。

使用Gen2<?>Gen2是您在运行时可以做的最好的事情。