Suppose I've a generic interface:
interface MyComparable> { public int compare(T obj1, T obj2); }
And a method sort
:
public static > void sort(List list, MyComparable comp) { // sort the list }
I can invoke this method and pass a lambda expression as argument:
List list = Arrays.asList("a", "b", "c"); sort(list, (a, b) -> a.compareTo(b));
That will work fine.
But now if I make the interface non-generic, and the method generic:
interface MyComparable { public > int compare(T obj1, T obj2); } public static > void sort(List list, MyComparable comp) { }
And then invoke this like:
List list = Arrays.asList("a", "b", "c"); sort(list, (a, b) -> a.compareTo(b));
It doesn't compile. It shows error at lambda expression saying:
"Target method is generic"
OK, when I compiled it using javac
, it shows following error:
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)int in interface MyComparable is generic) where T#1,T#2 are type-variables: T#1 extends Comparable declared in method sort(List,MyComparable) T#2 extends Comparable declared in method compare(T#2,T#2) 1 error
From this error message, it seems like compiler is not able to infer the type arguments. Is that the case? If yes, then why is it happening like this?
I tried various ways, searched through the internet. Then I found this JavaCodeGeeks article, which shows a way, so I tried:
sort(list, >(a, b) -> a.compareTo(b));
which again doesn't work, contrary to what that article claims that it works. Might be possible that it used to work in some initial builds.
So my question is: Is there any way to create lambda expression for a generic method? I can do this using a method reference though, by creating a method:
public static > int compare(T obj1, T obj2) { return obj1.compareTo(obj2); }
in some class say SO
, and pass it as:
sort(list, SO::compare);