为什么编译器会给出模糊的方法调用错误?

时间:2014-10-26 20:24:57

标签: java

以下是代码段。

class BoxVar{

       static void call(Integer... i){
           System.out.println("hi"+i);
       } 
       static void call(int... i ){
           System.out.println("hello"+i);
       }
       public static void main(String... args){
                     call(10);
     }
}

该程序编译良好。当我运行该程序时,它给了我

  

java:对调用的引用是不明确的,两种方法   com.exams.BoxVar中的call(java.lang.Integer ...)和方法调用(int ...)   在com.exams.BoxVar中匹配

有人可以解释一下原因吗?

除此之外,我尝试将第一种方法转换为类似的方法。

 static void call(Long... i){
               System.out.println("hi"+i);
           } 

运行正常。有人可以帮我解决这个问题吗?感谢。

2 个答案:

答案 0 :(得分:5)

编译器会准确地告诉您发生了什么。从概念上讲,Integerint类型是相同的。因此,两种方法签名都是相同的。

假设编译成功,编译器应该调用哪个方法?

类型LongInteger不一样(换句话说,编译器将整数类型视为两种不同的类型),这就是它成功编译的原因:

  

int:默认情况下,int数据类型是32位带符号的二进制补码整数,其最小值为-231,最大值为231-1。在Java SE 8及更高版本中,您可以使用int数据类型来表示无符号的32位整数,其最小值为0,最大值为232-1。使用Integer类将int数据类型用作无符号整数。有关更多信息,请参阅数字类一节。已经将诸如compareUnsigned,divideUnsigned等静态方法添加到Integer类中,以支持无符号整数的算术运算。

     

long:long数据类型是64位二进制补码整数。带符号的long的最小值为-263,最大值为263-1。在Java SE 8及更高版本中,您可以使用长数据类型来表示无符号的64位长,其最小值为0,最大值为264-1。当需要比int提供的值更宽的值时,请使用此数据类型。 Long类还包含compareUnsigned,divideUnsigned等方法,以支持unsigned long的算术运算。

请参阅Integral Types作为参考。

答案 1 :(得分:2)

您已经得到了关于您的程序无法编译的答案。我将添加Long的原因。

天真地,如果你使用类似的东西:

long longVal = 10;

编译器接受它并自动从int转换为long

但是这不适用于Long类型,它需要实际的long值:

Long longObj = 10; // Won't compile.

当编译器尝试解决歧义时,相同的原理也有效。如果您有两个具有相同名称的方法,但其中一个接受int而另一个接受Long,并且您尝试使用数字10调用它,则会识别出此数字是整数,并且它是& #39; s值不长,因此不会自动装入Long。

如果您使用值10L调用它,则会看到该数字很长,与int不兼容,但可以转换为Long

因此,在这种情况下尝试使用call(10)没有歧义。