14
public class MyClass {

    private String string;
    private Object[] objects;

    // constructor 1
    public MyClass(String string, Object... objects) {
        this.string = string;
        this.objects = objects;
    }

    // constructor 2
    public MyClass(String string) {
        this.string = string;
    }

    public static void main(String[] args) {
        MyClass myClass = new MyClass("foobar");
    }

}

在那种情况下,Java 编译器是如何决定使用constructor 2而不是 的constructor 1?为什么没有The constructor ... is ambiguous或类似的错误发生?

PS:这个问题也适用于经典方法

4

6 回答 6

7

仅当没有非var-arg方法/构造函数时才会选择var-args方法/构造函数。所以很清楚为什么编译器选择.MyClass(String string)

于 2012-10-29T11:16:30.767 回答
5

它总是被调用的最具体的方法。

new MyClass("foobar");

搜索以调用将类型对象String作为唯一参数的构造函数。

并且,如果匹配方法不存在,var-args则将使用方法。non-var-args

于 2012-10-29T11:19:43.077 回答
1

据我了解,可变参数构造函数和方法只是语法糖,它转换为数组声明。因此,您在编译期间的构造函数 1 几乎等于:

public MyClass(String string, Object[] objects) {
    this.string = string;
    this.objects = objects;
}

这意味着,如果您想MyClass通过以下代码构造实例:

MyClass obj = new MyClass("Hello", "1", "2");

这将等于:

MyClass obj = new MyClass("Hello", new Object[]{"1", "2"} );
于 2012-10-29T11:16:33.750 回答
0

第一个答案
当您有多个构造函数时,构造函数的参数声明彼此不同。初始化类时,Java 将调用与给定参数和类型匹配的正确构造函数。
例如:如果您创建 2 个具有相同参数的构造函数,那么它会显示给您Duplicate method or ambiguous error


具有相同和不同原型的第二个答案方法在java中称为方法重载。
这就是为什么no The constructor ... is ambiguous error occurs在承包商的情况下以及在方法的情况下。

于 2012-10-29T11:22:58.410 回答
0

JVM 将寻找精确匹配以将值传递给方法/构造函数中的变量,如果它无法找到精确匹配,它将把值视为对象。

于 2012-10-29T11:23:02.837 回答
0

jls-15.12.2声明编译器将首先在没有自动装箱或 var agrs 的情况下看起来最匹配Constructor #2适合你的情况。

如果它不存在,将应用第一个自动装箱,即任何具有参数超类 String ie Object 的方法都将被调用。

   // constructor 2
    public MyClass(Object string) {
        this.string = string.toString();
    }

现在,即使应用了自动装箱,编译器也无法找到最佳匹配,它会选择 var args。因此,如果您从代码中删除构造函数 2,将调用第一个构造函数。

于 2012-10-29T11:27:32.210 回答