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ですか? noThe 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

私が理解しているように、varargs コンストラクターとメソッドは、配列宣言に変換される構文シュガーにすぎません。したがって、コンパイル中のコンストラクター 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

jls-15.12.2は、コンパイラーが最初にオートボクシングやvaragrsなしで最適に見えると述べています。Constructor #2あなたのケースに合います。

そこになかった場合は、最初のオートボクシングが適用されます。つまり、パラメータが文字列のスーパークラスであるメソッド、つまりオブジェクトが呼び出されます。

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

これで、オートボクシングを適用した後でも、コンパイラーは最適なものを見つけることができず、varargsになります。したがって、コードからコンストラクター2を削除すると、最初のコンストラクターが呼び出されます。

于 2012-10-29T11:27:32.210 に答える
0

1 番目の回答
コンストラクターが複数ある場合、パラメーターの宣言によってコンストラクターが異なります。クラスが初期化されると、Java は指定された引数と型に一致する適切なコンストラクターを呼び出します。
例:同じパラメーターで2つのコンストラクターを作成すると、表示されますDuplicate method or ambiguous error

2番目の回答
同じプロトタイプと異なるプロトタイプを持つメソッドは、Javaではメソッドのオーバーロードと呼ばれます。
そのためno The constructor ... is ambiguous error occurs、メソッドの場合だけでなく、コントラクタの場合も同様です。

于 2012-10-29T11:22:58.410 に答える
0

JVM は、メソッド/コンストラクターの変数に値を渡すために完全一致を探します。完全一致が見つからない場合は、値をオブジェクトとして扱います。

于 2012-10-29T11:23:02.837 に答える