Giả sử tôi có một giao diện chung:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
Và một phương pháp sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
Tôi có thể gọi phương thức này và chuyển một biểu thức lambda làm đối số:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Điều đó sẽ hoạt động tốt.
Nhưng bây giờ nếu tôi làm cho giao diện không chung chung và phương pháp chung chung:
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) {
}
Và sau đó gọi điều này như:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Nó không biên dịch. Nó hiển thị lỗi ở biểu thức lambda nói:
"Phương pháp mục tiêu là chung"
OK, khi tôi biên dịch nó bằng cách sử dụng javac
, nó hiển thị lỗi sau:
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
Từ thông báo lỗi này, có vẻ như trình biên dịch không thể suy ra các đối số kiểu. Đó là trường hợp? Nếu có, thì tại sao nó lại xảy ra như thế này?
Tôi đã thử nhiều cách khác nhau, tìm kiếm trên internet. Sau đó, tôi tìm thấy bài viết JavaCodeGeeks này , trong đó chỉ ra một cách, vì vậy tôi đã thử:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
mà một lần nữa không hoạt động, trái với những gì bài báo đó tuyên bố rằng nó hoạt động. Có thể nó đã từng hoạt động trong một số bản dựng ban đầu.
Vì vậy, câu hỏi của tôi là: Có cách nào để tạo biểu thức lambda cho một phương thức chung không? Tuy nhiên, tôi có thể thực hiện việc này bằng cách sử dụng tham chiếu phương thức, bằng cách tạo một phương thức:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
trong một số lớp nói SO
, và chuyển nó dưới dạng:
sort(list, SO::compare);