Припустимо, у мене є загальний інтерфейс:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
І метод sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
Я можу викликати цей метод і передавати лямбда-вираз як аргумент:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Це буде добре.
Але тепер, якщо я роблю інтерфейс негенеричним, а метод загальним:
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) {
}
А потім посилайтеся на це так:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Він не компілюється. Він показує помилку при лямбда-виразі:
"Метод цілі є загальним"
Добре, коли я компілював його за допомогою javac
, він показує таку помилку:
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
З цього повідомлення про помилку здається, що компілятор не в змозі зробити висновок аргументів типу. Це так? Якщо так, то чому так відбувається?
Я пробував різні способи, шукав через Інтернет. Потім я знайшов цю статтю JavaCodeGeeks , яка показує спосіб, і я спробував:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
що знову не працює, всупереч тому, що ця стаття стверджує, що вона працює. Можливо, можливо, що вона працювала в деяких початкових побудовах.
Отже, моє питання: Чи є спосіб створити лямбда-вираз для загального методу? Я можу це зробити за допомогою посилання на метод, створивши метод:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
в якомусь класі говорять SO
і передають це як:
sort(list, SO::compare);