Genel bir arayüzüm olduğunu varsayalım:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
Ve bir yöntem sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
Bu yöntemi çağırabilir ve argüman olarak bir lambda ifadesi geçirebilirim:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Bu iyi çalışacak.
Ama şimdi arayüzü genel olmayan ve yöntemi genel yaparsam:
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) {
}
Ve sonra bunu şöyle çağırın:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Derlemez. Lambda ifadesinde şunu söyleyen hatayı gösterir:
"Hedef yöntem geneldir"
Tamam, kullanarak derlediğimde javac
aşağıdaki hatayı gösteriyor:
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
Bu hata mesajından, derleyicinin tür bağımsız değişkenlerini çıkaramadığı görülmektedir. Durum bu mu? Cevabınız evet ise, neden böyle oluyor?
İnternette araştırdım, çeşitli yollar denedim. Sonra bir yol gösteren bu JavaCodeGeeks makalesini buldum , bu yüzden denedim:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
bu makalenin işe yaradığını iddia ettiğinin aksine yine çalışmıyor. Bazı ilk yapılarda çalışıyor olması mümkün olabilir.
Öyleyse sorum şu: Genel bir yöntem için lambda ifadesi oluşturmanın herhangi bir yolu var mı? Bunu bir yöntem referansı kullanarak bir yöntem oluşturarak yapabilirim:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
bazı sınıflarda şunu söyleyin SO
ve geçin:
sort(list, SO::compare);