有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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 of SuperClass,in this case, SuperClass<Integer>. Remember, there is no generic type information available at run time. Therefore, there is no way for instanceof to know if s1 is an instance of SuperClass<Integer> or not.

有人能给我解释一下这些台词到底是什么意思吗


共 (3) 个答案

  1. # 1 楼答案

    在引擎盖下面,当使用泛型时,会发生一种称为类型擦除的情况。这意味着在将程序编译成字节码的过程中,泛型类型将转换为原始(非泛型)形式。所有类型参数都将成为对象,所有指定给类型变量的值都将转换为对象。这就是“运行时没有可用的泛型类型信息”的意思

    一行,如

    if(s1 instanceof SuperClass<Integer>)
    

    变成

    if(s1 instanceof SuperClass)
    

    编译后。在参数化类型上使用instanceof的问题是,在运行时,Java VM无法区分SuperClass<Integer>SuperClass<Double>等类型。如果编译器允许instanceof与参数化类型一起使用,那么前一行也会为SuperClass<Double>返回true,这可能会产生未定义的行为

    如果你想知道更多,甲骨文的网站有一个更全面的解释:https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast

  2. # 2 楼答案

    当你的。java文件被编译成。类文件,也称为字节码,SuperClass<Integer>这段代码被转换为SuperClass。这称为类型擦除。所以在运行时没有关于泛型类型的信息

  3. # 3 楼答案

    泛型信息是编译时特性。它在运行时被擦除。错误在this section of the Java Language Specification中解释:

    It is a compile-time error if the ReferenceType mentioned after the instanceof operator does not denote a reference type that is reifiable (§4.7).

    一个可重新定义的类型是defined,如下所示:

    Because some type information is erased during compilation, not all types are available at run time. Types that are completely available at run time are known as reifiable types.

    A type is reifiable if and only if one of the following holds:

    • It refers to a non-generic class or interface type declaration.

    • It is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1).

    • It is a raw type (§4.8).

    • It is a primitive type (§4.2).

    • It is an array type (§10.1) whose element type is reifiable.

    • It is a nested type where, for each type T separated by a ".", T itself is reifiable.

    因此,不允许像SuperClass<Integer>这样的参数化类型作为instanceof的引用类型。另一方面,允许SuperClass<?>