Java 为什么这个协变返回类型声明没有';你不会发出未经证实的警告吗?
为什么以下代码不生成编译时未检查警告:Java 为什么这个协变返回类型声明没有';你不会发出未经证实的警告吗?,java,jls,covariant-return-types,Java,Jls,Covariant Return Types,为什么以下代码不生成编译时未检查警告: class Parent { public List method(){ return null; } } class Child extends Parent { public List<String> method() { return null; } } 类父类{ 公共列表方法(){ 返回null; } } 类子级扩展父级{ 公共列表方法(){ 返回null; } }
class Parent {
public List method(){
return null;
}
}
class Child extends Parent {
public List<String> method() {
return null;
}
}
类父类{
公共列表方法(){
返回null;
}
}
类子级扩展父级{
公共列表方法(){
返回null;
}
}
而以下事实确实如此:
class Parent {
public List<String> method(){
return null;
}
}
class Child extends Parent {
public List method() {
return null;
}
}
类父类{
公共列表方法(){
返回null;
}
}
类子级扩展父级{
公共列表方法(){
返回null;
}
}
实际上,我正在JLS中寻找这种行为的参考。因为
List
不是List
的子类型,但是(如您所知)List
是List
的子类型
JLS中给出的示例:
class C implements Cloneable {
C copy() throws CloneNotSupportedException {
return (C)clone();
}
}
class D extends C implements Cloneable {
D copy() throws CloneNotSupportedException {
return (D)clone();
}
}
这是第一个示例,其中子对象中的返回类型是父对象的子类型。同样,在您的示例中,List
是List
的子类型
给定泛型类型声明C
(n>0),泛型的直接超类型
类型C
包括以下所有内容:
的直接超类C
的直接上级界面C
- 类型
,如果Object
是一种通用接口类型,没有直接的超级接口C
- 原始类型
(粗体矿)C
class StringSorter {
// turns a collection of strings into a sorted list
List<String> toList(Collection<String> c) {...}
}
class Overrider extends StringSorter {
List toList(Collection c) {...}
}
class-StringSorter{
//将字符串集合转换为排序列表
列表列表(集合c){…}
}
类重写器扩展了StringSorter{
列表列表(集合c){…}
}
是第二个代码片段的示例
编译重写器时,将针对
StringSorter
的新定义,因为
Overrider.toList
是List
,它不是
被重写的方法,列表
。(扫雷)
示例&特别是:
如果返回类型为R1的方法声明d1重写或隐藏
声明另一个返回类型为R2的方法d2,则d1必须为
d2的返回类型可替换(§8.4.5),或编译时错误
发生
此规则允许协变返回类型-优化返回类型
重写某个方法时对该方法的调用
如果R1不是R2的子类型,则会出现编译时未检查警告
除非被SuppressWarnings
注释(§9.6.4.5)抑制
查找。@DimaSan它实际上并没有解释为什么我的第一个示例不生成编译警告,而后面的示例生成编译警告。List
是原始List
的子类型吗?@JaimeHablutzel,“原始类型是没有任何类型参数的泛型类或接口的名称。”因此,List
是一个定义了其类型参数的列表。从JLS中,如果R1不是R2的**子类型**,则会出现编译时未检查警告,除非SuppressWarnings注释(§9.6.4.5)抑制该警告。
和您的语句,这是您的第一个示例,其中子对象中的返回类型是父对象的子类型。
,这将解释为什么在我的第一个示例中没有发出警告,但我无法在JLS中清楚地找到它,其中指出列表
实际上是列表
的子类型,请澄清。“原始”类型应用于遗留代码;他们放弃了类型检查。因此,您可以向它添加任何您想要的内容,而它不关心您是将字符串
s还是整数
s(一起)提供给它;这都是它的Object
s。因此,我不认为在这种情况下有理由发出未经检查的警告。JLS是否明确指出List
是原始类型List
的子类型,我需要花一点时间来详细说明。我将离线几个小时@JaimeHablutzel@JaimeHablutzel,真是个好发现!。我在答案中加入了你发现的必要部分,使之完整。我现在明白了,我太强调第二部分了,而第一部分正是你所问的;道歉。