Misalkan saya memiliki antarmuka umum:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
Dan metode sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
Saya bisa memanggil metode ini dan meneruskan ekspresi lambda sebagai argumen:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Itu akan bekerja dengan baik.
Tetapi sekarang jika saya membuat antarmuka non-generik, dan metode generik:
interface MyComparable {
public <T extends Comparable<T>> int compare(T obj1, T obj2);
}
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable comp) {
}
Dan kemudian panggil ini seperti:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Itu tidak dapat dikompilasi. Ini menunjukkan kesalahan pada ekspresi lambda yang mengatakan:
"Metode target bersifat umum"
Oke, ketika saya kompilasi menggunakan javac
, itu menunjukkan kesalahan berikut:
SO.java:20: error: incompatible types: cannot infer type-variable(s) T#1
sort(list, (a, b) -> a.compareTo(b));
^
(argument mismatch; invalid functional descriptor for lambda expression
method <T#2>(T#2,T#2)int in interface MyComparable is generic)
where T#1,T#2 are type-variables:
T#1 extends Comparable<T#1> declared in method <T#1>sort(List<T#1>,MyComparable)
T#2 extends Comparable<T#2> declared in method <T#2>compare(T#2,T#2)
1 error
Dari pesan error ini, sepertinya compiler tidak dapat menyimpulkan argumen type. Apakah itu masalahnya? Jika ya, mengapa bisa terjadi seperti ini?
Saya mencoba berbagai cara, mencari melalui internet. Kemudian saya menemukan artikel JavaCodeGeeks ini , yang menunjukkan caranya, jadi saya mencoba:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
yang lagi-lagi tidak berfungsi, bertentangan dengan klaim artikel itu bahwa itu berfungsi. Mungkin itu dulu berfungsi di beberapa build awal.
Jadi pertanyaan saya adalah: Apakah ada cara untuk membuat ekspresi lambda untuk metode umum? Saya dapat melakukan ini menggunakan referensi metode, dengan membuat metode:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
di beberapa kelas katakan SO
, dan berikan sebagai:
sort(list, SO::compare);