Java 原始类型和子类型
我们有通用类Java 原始类型和子类型,java,compiler-construction,raw-types,Java,Compiler Construction,Raw Types,我们有通用类 SomeClass<T>{ } SomeClass{} 我们可以这样写: SomeClass s= new SomeClass<String>(); SomeClass s=newsomeclass(); 没关系,因为原始类型是泛型类型的超类型。但是 SomeClass<String> s= new SomeClass(); SomeClass s=newsomeclass(); 这是正确的。为什么它是正确的?我以为是在进行类型检查之
SomeClass<T>{ }
SomeClass{}
我们可以这样写:
SomeClass s= new SomeClass<String>();
SomeClass s=newsomeclass();
没关系,因为原始类型是泛型类型的超类型。但是
SomeClass<String> s= new SomeClass();
SomeClass s=newsomeclass();
这是正确的。为什么它是正确的?我以为是在进行类型检查之前进行了类型擦除,但这是错误的
从黑客指南到Javac
当使用默认编译策略调用Java编译器时,它将执行以下过程:
泛型是语法糖,因此在类型检查之后,在第6遍调用类型擦除,而类型检查在第4遍调用。我很困惑。类型参数肯定参与类型检查;否则它将毫无意义(即不比原始类型好) 生成隐式强制转换时也需要这些信息,这样它将作为调试符号保存到步骤7,并在技术上保存到运行时。但是,只有擦除才会参与运行时类型转换检查(出于明显的向后兼容性原因)。尽管如此,如果您的泛型代码可以进行完全静态检查,那么它可以与非类型擦除语言中的泛型程序一样强大
当您将
SomeClass
分配给SomeClass
时,编译器将向您发出有关原始类型使用的警告。此时,您的程序显然不再安全。泛型不是语法糖,SomeClass和SomeClass是微妙的不同类型。允许将原始类型赋值给泛型类型,以支持与旧代码的互操作。@ice phoenix解释了这一点。但是在什么时候调用类型擦除呢?在类型检查之前的第2步或第4步?第7步,生成JVM字节码时删除泛型,编译器总是知道变量的完整泛型类型。@ice phoenix第7步,据我所知,这不是真的。看,我认为,这是第4步,在类型检查之后。看见