java中通用层次结构中的运行时类型比较

时间:2015-07-05 18:54:55

标签: java generics instanceof

我无法从完整参考中理解此文字 代码就是这个,

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>)此行无法编译,因为它尝试将s1与特定类型的SuperClass进行比较,在本例中为SuperClass<Integer>。请记住,运行时没有可用的通用类型信息。因此,instanceof无法知道s1是否是SuperClass<Integer>的实例。

有人可以解释一下这些线的含义究竟是什么意思?

3 个答案:

答案 0 :(得分:2)

当.java文件被编译为.class文件(也称为字节代码)时,SuperClass<Integer>这段代码将转换为SuperClass。这称为类型擦除。因此在运行时没有关于泛型类型的信息。

答案 1 :(得分:1)

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

  

如果instanceof运算符后面提到的 ReferenceType 不表示可恢复(第4.7节)的引用类型,则为编译时错误。

可恢复的类型为defined

  

由于在编译期间会删除某些类型信息,因此并非所有类型在运行时都可用。在运行时完全可用的类型称为可再现类型。 / p>      

当且仅当下列之一成立时,类型可以恢复

     
      
  • 它指的是非泛型类或接口类型声明。

  •   
  • 这是一种参数化类型,其中所有类型参数都是无界通配符(§4.5.1)

  •   
  • 这是一种原始类型(§4.8)。

  •   
  • 这是一种原始类型(§4.2)。

  •   
  • 这是一个数组类型(第10.1节),其元素类型是可以恢复的。

  •   
  • 这是一种嵌套类型,对于每个以“。”分隔的T类型,T本身都是可以恢复的。

  •   

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

答案 2 :(得分:1)

在使用泛型时,会发生一种叫做类型擦除的事情。这意味着在将程序编译为字节码的过程中,泛型类型将转换为其原始(非泛型)形式。所有类型参数都只是Object,并且分配给类型变量的所有值都被转换为Object。这就是&#34;&#34;在运行时没有可用的通用类型信息&#34;。

诸如

之类的行
if(s1 instanceof SuperClass<Integer>)

变为

if(s1 instanceof SuperClass)
编译后

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

如果您想了解更多信息,Oracle的网站会有更全面的解释:https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast