【问题标题】:Rules for selection an overloaded method with multiple parameters in JavaJava中选择具有多个参数的重载方法的规则
【发布时间】:2013-09-12 15:13:27
【问题描述】:

我知道 Java 中的重载规则,但在某些情况下我的直觉不起作用。

让我们考虑一个例子:

public class Overloading {
    public static void main(String[] args) {
        long primitive = 3;
        Long boxed = Long.valueOf(5);
        doWork(primitive, boxed);     //1
        doWork(boxed, boxed);         //2
        doWork(primitive, primitive); //3                
    }

    static void doWork(Long a, Long b) {}

    static void doWork(long a, Long b) {} 
}

你知道什么(1、2或3)会编译成功吗?

第一个和第二个会,但第三个不会(由于雄心勃勃的方法调用)。

为什么javac是这样设计的,不能解决这种情况?为什么不将#3 转换为#1?

【问题讨论】:

  • Java 应该为您选择哪一种实现方式?这种模棱两可正是实现者选择返回错误的原因。
  • @alfasin 我希望 java 可以选择一个具有最少自动装箱操作的选项。我错了,这句话:“另外:编译器不能总是根据需要的自动(取消)装箱次数选择最具体的方法。”从 Sotirios 提出的主题中进行了解释。谢谢!

标签: java compiler-errors overloading primitive-types autoboxing


【解决方案1】:

好问题!

您建议将 #3 转换为 #1 似乎是有道理的,因为它少了一个自动装箱操作。

这可能是 Java 决定给你一个错误而不是选择涉及最少装箱的方法的原因:

  1. 这种情况很少
  2. 找出用于自动装箱的方法可能昂贵*。
  3. 选择哪种方法的逻辑可能过于主观
  4. 因此,在这种情况下,Java 会强制您不要模棱两可

*Sotirios 链接到的accepted answer to the question 提供了一些关于为什么它可能过于昂贵而不值得的见解。

【讨论】:

  • 这与算法昂贵没有任何关系——主要是出于向后兼容性的原因。
  • @assylias 关于向后兼容性的要点;出于这个原因,Java 不想在未来的版本中更改规则。但是当这成为一个问题时,它仍然提出了关于 Java 1.5 中最初决定的问题。
【解决方案2】:

第一个和第二个会,但第三个不会(由于方法调用不明确)。为什么java不能 解决这种情况?为什么不将#3 转换为#1?

正如您所提到的,long 可以自动装箱为 Long。 然而,这里有一个歧义——如果只有第二个 long 被自动装箱,你会得到 #1。如果它们都被自动装箱,你会得到 #2。

由于 Java 无法确定您所指的方法,因此会引发错误。

【讨论】:

  • 理论上,Java 本来可以设计为选择其中一种方法而不是另一种方法——我认为 Dmitri 的问题是为什么它不是这样设计的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多