6

可能重复:
可变参数和重载的错误?

谁能解释一下这个是如何工作的:

class Vararg {
    static void vararg(int... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) { 
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}

获取编译时错误

class Vararg {
    static void vararg(Integer... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) {
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}

还会出现编译时错误。当我们使用可变参数重载时的机制是什么?这是重载可变参数方法的错误吗?

4

2 回答 2

16

In substance, to determine which method is applicable, the compiler runs a few steps:

  • first trying to find a method without using boxing/unboxing or varargs
  • second trying to find a method, allowing boxing / unboxing, but without varargs
  • third allowing boxing, unboxing and varargs

In your case, the third step is applicable to all methods.

The compiler then determines which methods are applicable and if one is more specific than another. The detailed rules are in the JLS 15.12.2.4. In short, it looks at the types and checks if one is more specific than another (i.e. one type is a subclass of the other for references or one type is narrower than another for primitives).

In your case:

  • in example 1, both methods are applicable but int is more specific than long so the vararg(int...) is chosen
  • in example 2, Integer has no specificity relationship with long (one is a reference the other is a primitve), so both are maximally specific and there is an ambiguity which leads to a compile error.

EDIT

I thought you were saying that your first example compiles but not the second (which is the expected behaviour). You seem to be saying that neither compiles, in which case it is probably due to a bug in you version of javac, which has been fixed with Java 7. See details in the release notes, section called "Changes in Most Specific Varargs Method Selection".

于 2013-02-05T13:37:20.550 回答
0

由于您在 vararg(type... var) 方法中发送了 int 值,并且重载的方法包含一个 Integer 和一个 long 因此,int 值会自动转换为 long 并因此产生歧义。在重载方法中使用不同的参数类型。

class Vararg {
static void vararg(Integer... x) {
    System.out.println("Integer..."); 
}

static void vararg(String... x) {
    System.out.println("String..."); 
}

public static void main(String [] args) {
    int s = 0;
    vararg(s,s);
}

}

于 2013-02-05T13:40:17.327 回答