java中泛型层次结构中的运行时类型比较
我无法从完整的参考资料中理解本文 代码是这样的
public class Generic
{
public static void main(String[] args)
{
SuperClass<Integer> s1=new SuperClass<>(135);
SubClass<Double> s2=new SubClass<>(1.35);
if(s1 instanceof SuperClass<Integer>)
{
System.out.println("I am instance of SuperClass");
}
}
}
class SuperClass<T>
{
T y;
SuperClass(T ob)
{
y=ob;
}
T ret()
{
return(y);
}
}
class SubClass<T> extends SuperClass<T>
{
T x;
SubClass(T y)
{
super(y);
x=y;
}
}
根据文本
if(s1 instanceof SuperClass<Integer>)
this line can’t be compiled because it attempts to compare s1 with a specific type ofSuperClass
,in this case,SuperClass<Integer>
. Remember, there is no generic type information available at run time. Therefore, there is no way forinstanceof
to know ifs1
is an instance ofSuperClass<Integer>
or not.
有人能给我解释一下这些台词到底是什么意思吗
# 1 楼答案
在引擎盖下面,当使用泛型时,会发生一种称为类型擦除的情况。这意味着在将程序编译成字节码的过程中,泛型类型将转换为原始(非泛型)形式。所有类型参数都将成为对象,所有指定给类型变量的值都将转换为对象。这就是“运行时没有可用的泛型类型信息”的意思
一行,如
变成
编译后。在参数化类型上使用
instanceof
的问题是,在运行时,Java VM无法区分SuperClass<Integer>
和SuperClass<Double>
等类型。如果编译器允许instanceof
与参数化类型一起使用,那么前一行也会为SuperClass<Double>
返回true,这可能会产生未定义的行为如果你想知道更多,甲骨文的网站有一个更全面的解释:https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast
# 2 楼答案
当你的。java文件被编译成。类文件,也称为字节码,
SuperClass<Integer>
这段代码被转换为SuperClass
。这称为类型擦除。所以在运行时没有关于泛型类型的信息# 3 楼答案
泛型信息是编译时特性。它在运行时被擦除。错误在this section of the Java Language Specification中解释:
一个可重新定义的类型是defined,如下所示:
因此,不允许像
SuperClass<Integer>
这样的参数化类型作为instanceof
的引用类型。另一方面,允许SuperClass<?>