我面对相同的代码:
public class Devk{
public static void tMeth(Integer... i){
System.out.print("A");
}
public static void tMeth(int... i){
System.out.print("B");
}
public static void main(String args[]){
tMeth(Integer.valueOf("7"));//compile error
tMeth(new int[2]); //returns B
tMeth(new Integer[2]); //returns A
}
}
在调用后我看到了
java: reference to tMeth is ambiguous, both method tMeth(java.lang.Integer...) in GenericsTest.Test1 and method tMeth(int...) in GenericsTest.Test1 match
方法Integer.valueOf("7")
返回Integer包装器。我希望在控制台中看到A
。
谁可以解释这种行为并为此提供一般规则?
P.S。
public static void tMeth(Integer i){
System.out.print("A");
}
public static void tMeth(int i){
System.out.print("B");
}
public static void main(String args[]){
tMeth(1); //returns B
tMeth(new Integer(1)); //returns A
}
答案 0 :(得分:6)
编译方法调用时,编译器按此顺序搜索匹配方法:
在你的情况下,你在这里的步骤(3)。由于允许拆箱,因此两种方法均适用。
然后编译器尝试找到最具体的那个。如果一种方法的参数类型具有相同或更具体的特征,则其中一种方法比另一种方法更具体(例如,String
比Object
更具体,int
比long
更具体})。
但在int
和Integer
之间,两者都不具体;编译器依赖于上面(2)之前的测试(1)来获得正确的方法,比如foo(int)
和foo(Integer)
。
因此,有两种适用的方法,两者都没有更具体,因此存在模糊性错误。
答案 1 :(得分:0)
此行为是由Java的自动装箱和Java的自动装箱引起的。
Java将自动将原始类型转换为其对应的包装类,并将包装类转换为其对应的基本类型。这使得可以将“int”传递给需要“整数”或“整数”的方法到需要“int”的方法。 Java将自动转换类型。
在您的特定情况下,这会导致歧义,因为有两种可能的方法可供调用。
您可以在此处详细了解 http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
答案 2 :(得分:-2)
Integer
(以及Double
,Byte
,Float
,Long
等)是原始数据类型的包装类。
自Java 5以来,由于自动装箱,您无法使用int
和另一个使用Integer
的方法,这会将任何int
变量转换为其Integer
对象(以及任何Integer
到int
,如果对象为NullPointerException
则提出null
。
答案 3 :(得分:-2)
这是因为一项名为“Autoboxing'在java中,给定的原始值将自动加入到它的包装类中。这里的原始值是int,包装类是Integer。由于7匹配原始值7和整数值7,因此两种方法都会发生冲突。
由于编译器会将原始值传递给匹配基元和包装器类型的参数(反之亦然,因为包装器类型),你实际上并没有像在复制它们那样重载方法。