以下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<?>
听起来在运行时没有可用的泛型类型信息。如果是的话,什么时候可用?我很困惑......
答案 0 :(得分:3)
在编译结束时,会出现type erasure,并且生成的字节码中不存在此类型信息。发生这种情况是因为Java需要保持与泛型前编写的代码的向后兼容性。 JVM没有泛型的概念。
泛型被引入到Java语言中,以便在编译时提供更严格的类型检查并支持泛型编程。为了实现泛型,Java编译器将类型擦除应用于:
- 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或对象。因此,生成的字节码只包含普通的类,接口和方法。
- 如有必要,插入类型转换以保护类型安全。
- 生成桥接方法以保留扩展泛型类型中的多态性。 类型擦除确保不为参数化类型创建新类;因此,泛型不会产生运行时开销。
instanceof
运算符本质上是一个运行时操作,因此它无法确定泛型类型参数是什么,因此编译器必须禁止instanceof
的泛型类型。
使用Gen2<?>
或Gen2
是您在运行时可以做的最好的事情。