Saya menemukan potongan ini:
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);
}
}
Ini akan menghasilkan kesalahan kompilasi:
Kesalahan: (15, 9) java: referensi ke printSum bersifat mendua baik metode printSum (int, dobel) di ParamTest dan metode printSum (panjang, panjang) di pertandingan ParamTest
Bagaimana ini ambigu? Bukankah hanya parameter kedua yang dipromosikan dalam kasus ini karena parameter pertama sudah menjadi int? Param pertama tidak perlu dipromosikan dalam kasus ini, kan?
Kompilasi berhasil jika saya memperbarui kode untuk menambahkan metode lain:
public static void printSum(int a, long b) {
System.out.println(String.format("%s, %s ", a, b));
}
Biarkan saya memperluas hanya untuk memperjelas. Kode di bawah ini menghasilkan ambiguitas:
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);
}
}
Maka kode di bawah ini juga menghasilkan ambiguitas:
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);
}
}
Namun yang ini tidak menghasilkan ambiguitas:
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);
}
}
java
java-8
type-promotion
riruzen
sumber
sumber
Error:(15, 9) java: reference to printSum is ambiguous both method printSum(int,double) in ParamTest and method printSum(long,long) in ParamTest match
- itu bukan metode yang ambigu, itu panggilan ke metode yang ambigu.Jawaban:
Saya pikir ini ada hubungannya dengan aturan spesifik JLS tentang 15.12.2.5. Memilih Metode Paling Spesifik . Ini menyatakan bahwa:
Bagaimana Java memilih metode yang paling spesifik dijelaskan lebih lanjut oleh teks:
Dalam hal contoh Anda, semua metode dapat diakses dan berlaku untuk pemanggilan metode, oleh karena itu, Java perlu menentukan yang mana yang paling spesifik .
Untuk metode ini, tidak ada yang dapat ditentukan lebih spesifik:
Metode keempat membersihkan ambiguitas justru karena memenuhi kondisi yang diperlukan untuk menjadi paling spesifik .
Yaitu, (int, long) dapat diteruskan ke (int, double), (long, long), atau (double, long) tanpa kesalahan kompilasi.
sumber
Ini memang pertanyaan yang sangat menarik. Mari kita pergi melalui Spesifikasi Bahasa Jawa langkah demi langkah.
Ketika kompiler mencoba mengidentifikasi metode yang berpotensi berlaku, hal pertama yang dilakukan adalah melakukan serching untuk metode yang dapat diterapkan oleh Strict Invocation .
Dalam kasus Anda tidak ada metode seperti itu, jadi langkah selanjutnya adalah menemukan metode yang dapat diterapkan oleh Loose Invocation
Pada titik ini semua metode cocok, sehingga metode yang paling spesifik ( §15.12.2.5 ) dipilih di antara metode-metode yang dapat diterapkan dengan doa lepas.
Ini adalah momen kunci, jadi mari kita lihat ini dari dekat.
(Kami hanya tertarik pada kasus berikut):
Sederhananya, suatu metode lebih spesifik jika semua tipe parameternya lebih spesifik . Dan
Ekspresi
S <: T
berartiS
subtipe dariT
. Untuk primitif kita memiliki hubungan sebagai berikut:Jadi mari kita lihat metode Anda dan lihat mana yang lebih spesifik daripada yang lain.
Dalam contoh ini parameter pertama metode 1 jelas lebih spesifik daripada parameter pertama metode 2 (jika Anda memanggilnya dengan nilai integer:)
printSum(1, 2)
. Tetapi parameter kedua lebih spesifik untuk metode 2 , karenalong < double
. Jadi tidak satu pun dari metode ini lebih spesifik daripada yang lain. Itu sebabnya Anda memiliki ambiguitas di sini.Dalam contoh berikut:
tipe parameter pertama dari metode 1 lebih spesifik daripada yang ada di metode 2, karena
int < long
dan tipe parameter kedua sama untuk keduanya, itu sebabnya metode 1 dipilih.sumber
double
tidak lebih spesifik darilong
. Dan untuk metode yang akan dipilih, semua parameter tipe harus lebih spesifik: tipe Si lebih spesifik daripada Ti untuk argumen ei untuk semua i (1 ≤ i ≤ n, n = k)karena nilai int juga dapat dianggap sebagai ganda di java. berarti
double a = 3
valid dan sama dengan panjanglong b = 3
Jadi itu sebabnya ia menciptakan ambiguitas. Kamu panggilMembingungkan untuk ketiga metode ini, karena ketiga metode ini valid:
Anda dapat menempatkan L di bagian akhir, untuk menentukan bahwa nilai itu panjang. sebagai contoh:
untuk gandakan Anda perlu mengubahnya:
juga membaca komentar @Erwin Bolwidt
sumber