微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java认证考试的重载方法

如何解决java认证考试的重载方法

我正在准备 Java 认证考试,但我不明白的一件事如下:

class Calculator {
    public static long add(int a,long... b) {
        System.out.println("int a,Var args long b");
        int total = a;
        for (long val : b) {
            total += val;
        }
        return total;
    }
    public static long add(int a,Long b) {
        System.out.println("int + Long");
        return a + b;
    }
}
public class OverloadTests {
    public static void main(String[] args) {
        var result = Calculator.add(1,2);
        System.out.println("result = " + result);
    }
}

Java 文档 (https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2) 说:

1- 第一阶段执行重载决议,不允许装箱或拆箱转换,或使用可变参数方法调用。如果在此阶段没有找到适用的方法,则处理继续第二阶段

2- 第二阶段执行重载决议,同时允许装箱和拆箱,但仍排除使用可变数量方法调用。如果在此阶段找不到适用的方法,则处理继续到第三阶段。

3- 第三阶段允许重载与可变数量方法、装箱和拆箱相结合。

所以,根据这些规则,我认为这应该发生:

  • Calculator.add(1,2); 寻找 (int,int) 签名,但没有找到。它还按照此顺序查找 (int,long)(int,float)(int,double)。由于我们处于第 1 步,因此我们没有寻找可变参数,我们不应该有匹配项。
  • 在这一步中,它执行装箱/拆箱。由于我们有 (int,Long),我预计结果是 "int + Long"
  • 在这一步中,它还会寻找可变参数,如果上一步没有,它应该已经找到了 "int a,Var args long b"

在这里错过了什么?我原以为结果是 "int + Long",但结果是 "int a,Var args long b"

编辑:代码取自作者 Java SE 11 Developer 1Z0-819 OCP Course - Part 1

的名为 Tim Buchalka 的 Udemy 课程

解决方法

如果你删除方法 add(int a,long... b) 你会发现你的代码不会编译因为剩下的方法 add(int a,Long b) 不能用 add(1,2) 调用,因为 2 是一个 int 和一个原始 int不能装箱成龙。同样,语句 Long a = 2; 是无效的。因此,唯一匹配的候选对象是 add(int a,long... b)

,

重载适用性规则植根于转换规则(JLS Ch5,“转换和上下文”)。定义了不同的转换(原始扩展(int to long)、装箱(int to Integer)、引用加宽(String to Object)等)。

在任何给定的情况下,任何给定的转换可能适用也可能不适用,具体取决于上下文。上下文包括赋值上下文、方法调用上下文、强制转换上下文等,重载解析第一阶段和后面阶段的区别在于严格调用上下文松散调用上下文的区别。 em>.

让您感到困惑的可能是 add(int,Long) 即使在松散的调用上下文中也不适用于 (int,int)。这是因为 (JLS 5.3) 后跟装箱转换的扩展原语转换不是调用上下文中允许的转换之一。如果您调用 add(0,0L),它将适用(装箱转换)。

可变参数情况适用于松散的上下文,因为存在从 intlong 的扩展原始转换。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。