java中重载方法优先级
我知道这个问题已经讨论过很多次了,但我还是不明白 研究此代码:java中重载方法优先级,java,overloading,Java,Overloading,我知道这个问题已经讨论过很多次了,但我还是不明白 研究此代码: public class Main { public static void var(Integer x, int y) { System.out.println("Integer int"); } public static void var(int... x) { System.out.println("int... x"); }
public class Main {
public static void var(Integer x, int y) {
System.out.println("Integer int");
}
public static void var(int... x) {
System.out.println("int... x");
}
public static void var(Integer... x) {
System.out.println("Integer...");
}
public static void main(String... args) {
byte i = 0;
Integer i2 = 127;
var(i, i2);
}
}
在我的大脑中,有以下规则:
int
Integer
,还有exist方法takesInteger
和int
打拳击
因此int
->Integer
和Integer
->int
参数
我认为这些论据是适用的,并期望看到
Integer int
在输出方面
但我明白了
int ...
为什么?现在很清楚,选择了方法
var(int…)
,而不是var(Integer…
原因是只允许应用某些转换,并且它只能是列表中的其中一个转换,而不是转换链。
java编译器不允许先进行扩展原语转换,然后再进行装箱转换
这是合同中规定的
5.3。方法调用转换
方法调用转换应用于
方法或构造函数调用(§8.8.7.1,§15.9,§15.12):类型
参数表达式的类型必须转换为
相应的参数
方法调用上下文允许使用以下内容之一:
- 身份转换(§5.1.1)
- 扩大原语转换(§5.1.2)
- 拓宽参考转换(§5.1.5)
- 装箱转换(§5.1.7)后可选加宽参考 转化
- 拆箱转换(§5.1.8)后可选加宽 原语转换
(字节,整数)
转换为(int,int)
它不能先将第一个参数byte
转换为int
,然后对同一个参数应用从int
到Integer
的装箱转换,因为不允许按顺序进行两次转换
让我们回到前一步,了解编译器如何选择要调用的重载方法。如中所述。(15.12.1描述了如何找到要搜索的类或接口,但我们已经知道我们想要调用classMain
中的静态方法)
编译器选择正确重载方法的前两个阶段不适用于变量参数(“变量arity”)方法,但第三个阶段适用:
第三阶段(§15.12.2.4)允许超载与
变量算术方法、装箱和取消装箱
第15.12.4节相当复杂,但此处适用的规则如下:
- 首先应用非变量算术参数的规则(不适用于您的情况)
- 调用中的每个变量参数都必须可以通过方法调用转换(我在上面复制的部分)转换为变量参数声明的类型
(字节,整数)
调用名为var
的方法var(Integer…
字节
转换为整数
(方法中声明的参数类型)吗字节
直接转换为整数
——它不能执行两个步骤var(Integer…
var(int…)
字节
转换为int
。这是一个复选标记整数
,它看到JLS 5.3允许编译器使用拆箱转换将其转换为int
。所以这也是一个复选标记var(int…)
是一个很好的匹配var
的方法,因此var(int…)
是唯一适用的方法。编译器现在将生成代码来进行必要的转换并调用该方法- 整数-->数字[确定!]
- 整型装箱到整型加宽到数字
- 字节-->整数[不编译]
- 字节需要先加宽到int,然后长方体加宽到整数。Java没有 允许吧。请注意,你不能这样做-字节框到字节然后 扩展为整数(整数不是字节的超类)
public class Overload{
public static void primitiveWiden(int x){
System.out.println("int");
}
public static void refWiden(Map m){
System.out.println("Map");
}
public static void priWideAndBox(Integer o){//doesn't work
System.out.println("Object");
}
public static void boxAndRefWide(Number n){//it works
System.out.println("Number");
}
public static void main(String[] args){
byte b =0;
int i =0;
HashMap m = new HashMap();
primitiveWiden(b);
refWiden(m);
priWideAndBox(b);//compile error
boxAndRefWide(i);
}
}
我希望看到这段代码没有编译,看起来我的期望是正确的:@OliCharlesworth可能是JDK问题?@OliCharlesworth我得到了相同的错误。@gstackoverflow。。你在哪个java版本上编译?@Rohit Jain抱歉。我更新了主题。这对我来说已经够复杂的解释了。你能解释一下描述简单的动作吗?如何思考编译器编译器如何解决重载问题吗?好的,我会补充一些关于它如何选择调用哪个方法的信息,有时候事情并不是那么清楚