私はこのスニペットつまずきました:
public class ParamTest {
public static void printSum(int a, double b) {
System.out.println("In intDBL " + (a + b));
}
public static void printSum(long a, long b) {
System.out.println("In long " + (a + b));
}
public static void printSum(double a, long b) {
System.out.println("In doubleLONG " + (a + b));
}
public static void main(String[] args) {
printSum(1, 2);
}
}
これは、コンパイルエラーになります:
エラー:(15、9)は、Java:printSumへの参照があいまいな両方法printSum(int型、ダブル)ParamTestとParamTest試合における方法printSum(長い長い)で
これはどのようにあいまいなのですか?最初のパラメータはすでにint型であるため、唯一の二番目のパラメータは、この場合に推進すべきではありませんか?この場合、右には促進されない最初のparam必要?
私は別のメソッドを追加するために、コードを更新した場合、コンパイルは成功します。
public static void printSum(int a, long b) {
System.out.println(String.format("%s, %s ", a, b));
}
私はちょうど明確にするために拡張してみましょう。曖昧で結果以下のコード:
public class ParamTest {
public static void printSum(int a, double b) {
System.out.println("In intDBL " + (a + b));
}
public static void printSum(long a, long b) {
System.out.println("In long " + (a + b));
}
public static void main(String[] args) {
printSum(1, 2);
}
}
そして、このコードは以下のも曖昧になり:
public class ParamTest {
public static void printSum(int a, double b) {
System.out.println("In intDBL " + (a + b));
}
public static void printSum(double a, long b) {
System.out.println("In doubleLONG " + (a + b));
}
public static void main(String[] args) {
printSum(1, 2);
}
}
しかし、この1つはしない曖昧になります:
public class ParamTest {
public static void printSum(int a, double b) {
System.out.println("In intDBL " + (a + b));
}
public static void printSum(long a, double b) {
System.out.println("In longDBL " + (a + b));
}
public static void main(String[] args) {
printSum(1, 2);
}
}
私はこれを約JLSの具体的なルールとは何かがあると思い15.12.2.5を。最も具体的な方法を選択します。これは、と述べています:
複数のメンバメソッドは、メソッドの呼び出しにアクセスし、該当の両方である場合、実行時のメソッドディスパッチのための記述を提供するために、いずれかを選択する必要があります。Javaプログラミング言語は、最も具体的な方法が選択されていることをルールを使用しています。
どのようにJavaが選ぶ最も具体的な方法は、さらに、テキストで説明されています。
非公式直感、第1の方法で扱う任意の呼び出しがコンパイル時エラーなしで他方に渡すことができれば一つの方法は、別のより特異的であることです。そのような明示的に型付けされたラムダ式引数(§15.27.1)または可変のアリティ呼び出し(§15.12.2.4)などの場合には、ある程度の柔軟性は、他の1人の署名を適応させることができます。
あなたの例の場合は、すべてのメソッドがアクセス可能で、メソッド呼び出しに適用され、そのため、Javaがあり、それらのどれかを決定する必要があり、最も特定。
これらのメソッドについては、どれも、より具体的に決定することはできません。
public static void printSum(int a, double b) {
System.out.println("In intDBL " + (a + b));
} // int, double cannot be passed to long, long or double, long without error
public static void printSum(long a, long b) {
System.out.println("In long " + (a + b));
} // long , long cannot be passed to int, double or double, long without error
public static void printSum(double a, long b) {
System.out.println("In doubleLONG " + (a + b));
} // double, long cannot be passed to int, double or long, long without error
それがために必要な条件を満たしているため、第四の方法は、正確にあいまいさをクリア最も特定。
public static void printSum(int a, long b) {
System.out.println(String.format("%s, %s ", a, b));
}
すなわち、(int型は、長い)コンパイルエラーなし(ダブル、長い)、(int型、ダブル)に渡された(長い、長い)、またはすることができます。