今天这个代码编译时我很惊讶:
class GenericClass<T> {
public void emptyMethod(T instance) {
// ..
}
public void print(T instance) {
System.out.println(instance);
}
}
public class Main {
public static void main(String[] args) {
GenericClass first = new GenericClass();
System.out.println("Wow");
first.emptyMethod(10);
first.print(16);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器发出警告(类型安全:方法emptyMethod(Object)属于原始类型GenericList.对泛型类型GenericList的引用应该参数化),但无论如何它不会导致编译器错误并且它运行'正常'(至少提供的打印方法).正如我所理解的,编译器使用object作为类型参数,但我觉得它反直觉.为什么编译器会这样做呢?为什么它不要求我指定类型参数?
你基本上是在使用原始类.
回想一下在Java中首次引入泛型时:已经使用了大量代码List
,ArrayList
等等.为了避免破坏所有代码,但仍然重用现有类,引入了原始类型 - 它基本上使用了泛型输入好像不是一个.
正如你所看到的,你得到一个警告 - 所以值得避免 - 但这是它被允许的主要原因.
有关更多信息,请参阅JLS的4.8节,其中包括:
原始类型与通配符密切相关.两者都基于存在类型.原始类型可以被认为是通配符,其类型规则是故意不合理的,以适应与遗留代码的交互.从历史上看,原始类型先于通配符; 它们最初是在GJ中引入的,并在文章中描述了过去的未来安全:Gilad Bracha,Martin Odersky,David Stoutamire和Philip Wadler在Java编程语言中添加了通用性,参见ACM会议论文集 - 面向编程,系统,语言和应用(OOPSLA 98),1998年10月.
归档时间: |
|
查看次数: |
157 次 |
最近记录: |