【问题标题】:Why is the Short method calling the integer method?为什么 Short 方法调用整数方法?
【发布时间】:2015-09-14 16:49:41
【问题描述】:
public class Yikes {
public static void go(Long n) {
System.out.print("Long ");
}
public static void go(Short n) {
System.out.print("Short ");
}
public static void go(int n) {
System.out.print("int ");
}
public static void main(String[] args) {
short y = 6;
long z = 7;
go(y);
go(z);
}
}
这个程序给出了输出
int Long
我以为输出是
short Long
这是什么原因?
【问题讨论】:
标签:
java
overload-resolution
【解决方案1】:
overload resolution section in the JLS 解释了原因:
- 第一阶段 (§15.12.2.2) 执行重载决议不允许装箱或拆箱转换,或使用可变的 arity 方法调用。如果在此阶段未找到适用的方法,则处理继续到第二阶段。
这保证了在 Java SE 5.0 之前在 Java 编程语言中有效的任何调用都不会因为引入可变数量方法、隐式装箱和/或拆箱而被认为是模棱两可的。但是,变量 arity 方法的声明(第 8.4.1 节)可以更改为给定方法方法调用表达式选择的方法,因为变量 arity 方法在第一阶段被视为固定 arity 方法。例如,在已经声明 m(Object) 的类中声明 m(Object...) 会导致不再为某些调用表达式选择 m(Object)(例如 m(null)),因为 m(Object[]) 更具体。 p>
- 第二阶段 (§15.12.2.3) 执行重载决议,同时允许装箱和拆箱,但仍排除使用可变参数方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。
在第一阶段,编译器在其解析中不包括方法go(Short n)。相反,它认为go(int n) 是一种适用的方法。此方法适用,因为 short 正在扩大转换为 int。
【解决方案2】:
编译器更愿意将short 转换为int,而不是将其装箱为Short 对象。
【解决方案3】:
试试这个:
代替
public static void go(Short n) {
System.out.print("Short ");
}
试试
public static void go(short n) {
System.out.print("Short ");
}