kee*_*420 3 java methods overloading java-11
我正在准备 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);
}
}
Run Code Online (Sandbox Code Playgroud)
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作者命名的 Udemy 课程Tim Buchalka
如果删除该方法,add(int a, long... b)您会发现您的代码将无法编译,因为add(int a, Long b)无法调用剩余的方法,add(1, 2)因为 2 是一个 int 并且原始 int 不能装箱到 Long 中。同样,该语句Long a = 2;无效。因此唯一匹配的候选是add(int a, long... b)。
重载适用性的规则植根于转换规则(JLS Ch5,“转换和上下文”)。定义了不同的转换(原始加宽(int 到 long)、装箱(int 到 Integer)、引用加宽(String 到 Object) ), ETC)。
在任何给定情况下,任何给定转换可能适用也可能不适用,具体取决于上下文。上下文包括赋值上下文、方法调用上下文、强制转换上下文等,重载决策第一阶段和后面阶段的区别就是严格调用上下文和松散调用上下文的区别。
让您困惑的可能是即使在松散的调用上下文中add(int, Long)也不适用(int, int)。这是因为 (JLS 5.3) 后跟装箱转换的加宽基元转换不是调用上下文中允许的转换之一。如果您调用add(0, 0L)它,它将适用(拳击转换)。
varargs 情况适用于松散上下文,因为存在从int到的扩大原始转换long。
| 归档时间: |
|
| 查看次数: |
122 次 |
| 最近记录: |