我正在阅读jls,但遇到了以下术语:

return-type-substitutable


来自jls的片段


  返回类型为R1的方法声明d1为
  返回类型可替换具有返回类型R2的另一个方法d2
  如果满足以下任何条件,则为:
  
  如果R1为空,则R2为空。
  
  如果R1是原始类型,则R2与R1相同。
  
  如果R1是引用类型,则下列条件之一为真:
  
  --R1是d2的类型参数(第8.4.4节)的子类型,它是的子类型
  R2
  
  --R1可以通过未经检查的转换转换为R2的子类型
  (第5.1.9节)。
  
  --d1与d2(第8.4.2节)的签名不同,并且R1 = | R2 |。


前两点很明显。

你能澄清一下吗


  --R1是d2的类型,它适合d2(第8.4.4节)的类型参数。
  
  可以通过未经检查的转换将--R1转换为R2的子类型(第5.1.9节)。
  
  --d1与d2(第8.4.2节)的签名不同,并且R1 = | R2 |。


谢谢

附言
对于Luiggi Mendoza

interface Foo {
        List<String> foo(String arg1, String arg2);
}

class Bar implements Foo {
    @Override
    public ArrayList<String> foo(String arg1, String arg2) {
        //implementation...
        return  null;
    }

    public String foo(String arg1, String arg2, String arg3) {
        //implementation...
        return  null;
    }
}


它正在工作。

我的问题的原因-我想从jls理解以下短语:


  如果返回类型为R1的方法声明d1覆盖或隐藏了
  声明另一个具有返回类型R2的方法d2,则d1必须为
  d2的return-type-substabletable(§8.4.5)或编译时错误
  发生


规则:

If R1 is a reference type then **one of the following** is true:
...
--d1 does not have the same signature as d2 (§8.4.2), and R1 = |R2|.
...


码:

interface Foo {
        List<String> foo(String arg1, String arg2);
}

class Bar implements Foo {
    @Override
    public List<String> anotherName(String arg1, String arg2,Object obj) {
           return  null;
    }


这是编译错误。

R1 == R2(List<String > == List<String>

d1!= d2

我在哪里违反规则?

最佳答案

让我们有这个界面

interface Foo {
    List<String> foo(String arg1, String arg2);
}


和一个实现它的类

class Bar implements Foo {
    @Override
    public List<String> foo(String arg1, String arg2) {
        //implementation...
    }
}


我们有:


Bar#foo作为d1
List<String>返回d1中的R1类型。
Foo#foo作为d2
List<String>在d2中返回类型为R2。



  适应d2(§8.4.4)类型参数的R1是R2的子类型。


这意味着R1可以是R2的子类型,这意味着R1应该通过IS-A测试。因此,我们可以执行以下操作:

class Bar implements Foo {
    @Override
    public ArrayList<String> foo(String arg1, String arg2) {
        //implementation...
    }
}



  R1可以通过未经检查的转换(§5.1.9)转换为R2的子类型。


这与泛型更相关。这意味着,即使R1会引发未检查的覆盖警告,也应通过IS-A测试。因此,我们可以执行以下操作:

class Bar implements Foo {
    @Override
    public ArrayList foo(String arg1, String arg2) {
        //implementation...
    }
}



  d1与d2(§8.4.2)具有不同的签名,并且R1 = | R2 |


这意味着重载:

class Bar implements Foo {
    @Override
    public ArrayList<String> foo(String arg1, String arg2) {
        //implementation...
    }

    public ArrayList<String> foo(String arg1, String arg2, String arg3) {
        //implementation...
    }
}

07-24 19:02
查看更多