Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这个协变返回类型声明没有';你不会发出未经证实的警告吗?_Java_Jls_Covariant Return Types - Fatal编程技术网

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,真是个好发现!。我在答案中加入了你发现的必要部分,使之完整。我现在明白了,我太强调第二部分了,而第一部分正是你所问的;道歉。