【问题标题】:Why return type cannot change when overloading a method in Java [duplicate]为什么在Java中重载方法时返回类型不能改变[重复]
【发布时间】:2015-06-10 04:51:17
【问题描述】:

我知道要重载 Java 中的方法,我们需要更改参数中的某些内容,无论是参数的数量还是其中至少一个参数的类型。这种方式在编译时编译器能够静态绑定将被调用的方法,但我只是想知道为什么改变方法的返回类型还不够,第一个响应是因为歧义,但在我的如果我们有意见:

public class Test {
    public Integer method1(Integer a, Integer b) {
        return a + b;
    }

    public String method1(Integer a, Integer b) {
        return "test";
    }

    public static void main(String[] args) {
        String result = method1(2, 4);
    }
}

我知道这段代码无法编译,但我的问题是:编译器是否有可能检查我们期望的返回类型并基于此将调用绑定到正确的方法?

编辑:我想在我的问题中非常清楚我知道只有参数是方法签名的一部分,我知道我们可以让方法不返回任何内容,所以我们有一个歧义,所以编译应该提出错误,但是我们完全没有歧义的情况呢?就像我提出的例子......这可行吗?有人知道不这样做的特殊原因吗?

【问题讨论】:

  • 如何编译Object o = method1(2, 4);。或者干脆method1(2, 4);
  • 如果我想在不存储返回值的情况下调用method1(1, 2); 之类的方法怎么办? JVM 应该调用什么?
  • @Tom 总是可以发明规则,例如,可能缺少返回目标会导致歧义错误。这就是为什么像这样的问答完全是推测性的。
  • @Radiodef 如果您需要将返回值存储在临时变量中,以避免编译器错误,这样的规则可能真的很烦人。但无论如何我都会考虑这种重载代码的味道,所以我不会接触这个规则:D。
  • 对此有很多答案。只需搜索“方法重载 java 返回类型”。

标签: java


【解决方案1】:

方法重载基于更改方法的签名。由于方法does not include the return type的签名,你必须单独在参数上区分这两个方法。

From the Java Language Specification唯一组成方法的签名和构造函数声明的是它的名称和它的参数类型。

两个方法具有相同的签名,如果它们具有相同的名称和 参数类型。

两个方法或构造函数声明 M 和 N 具有相同的参数 如果满足以下所有条件,则类型:

  • 它们具有相同数量的形参(可能为零)

  • 它们具有相同数量的类型参数(可能为零)

  • 设 A1, ..., An 为 M 的类型参数,设 B1, .. ., Bn 为 N 的类型参数。 在将 N 的类型中出现的每个 Bi 重命名为 Ai,对应类型变量的边界是 相同,M和N的形参类型相同。

方法 m1 的签名是 a 的签名的子签名 方法 m2,如果:

  • m2 与 m1 具有相同的签名,或者

  • m1 的签名与 m2 的签名擦除(第 4.6 节)相同。

两个方法签名 m1 和 m2 是 覆盖等效当且仅当 m1 是 m2 或 m2 是 m1 的子签名。

在一个类中声明两个具有重写等效签名的方法是编译时错误。

那个,那个单独是你的语句不能编译的原因;您将 IntegerInteger 传递给两个相同的*方法,Java 无法消除它们之间的歧义。

这意味着这样的声明是完全合法的

public Integer method1(Integer a, Integer b) {
    return null;
}

public void method1(Integer c) {
}

...因为两种方法的参数类型不同。

*:就编译器而言,“相同”。

【讨论】:

  • 这是 OP 已经知道的。他问为什么返回类型不足以用于方法重载(或者为什么返回类型不是签名的一部分)。
  • 我添加了来自 JLS 的引用,以强调在方法的签名中明确不考虑返回类型。
  • 我可以得到这个答案。用事实来回答,因为这是我们能给出的答案。
  • @Tom:唯一能够明确回答为什么这不是签名的一部分的人是语言设计者自己。它也可能是 C 的保留,其中函数的签名是它的名称和参数类型。
  • 对。所以,我想我要做的是明确说明参考来自语言规范。那应该满足它的为什么部分;该语言已明确禁止它。 @Tom,我不完全确定为什么我没有足够简洁地解释它的整个来回是什么。事实仍然存在 - 语言已经禁止它。
【解决方案2】:

您可以通过询问自己在以下场景中将调用哪个方法来回答这个问题:

public static void main(String[] args) {
    Object result = method1(2, 4);
}

【讨论】:

  • 很明显,返回 Object 的那个会被调用或引发歧义错误。这究竟如何验证或使 OP 的建议无效?
  • 该操作没有提出任何建议,而是提出了一个问题,在我看来,我写的内容已经回答了这个问题。我不想让他的问题无效,而是给他指点如何自己得到答案。
  • muued ,但你建议的情况,要么我们有歧义,所以我们得到一个编译错误,或者我们可以添加一个新方法,专门返回一个对象。但在我们完全没有歧义的情况下,就像我提出的那样,目前还不清楚为什么这不可行。
  • “这是 - 在我看来 - 我写的回答” 但你没有解释如何。而且,正如我所指出的,可以发明规则来处理您的答案中的情况,就像 OP 建议发明规则以允许这样做一样。 Java 语言有处理重载歧义的规则,那么为什么您认为歧义与答案相关?
  • stackoverflow.com/a/2745051/3661794 更详细地介绍了允许基于返回类型的方法重载的麻烦
猜你喜欢
  • 2011-05-18
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
  • 2015-05-16
  • 2014-12-29
  • 2011-05-20
相关资源
最近更新 更多