Lambda-Ausdruck und generische Methode

Angenommen, ich habe eine generische Schnittstelle:

interface MyComparable<T extends Comparable<T>>  {
    public int compare(T obj1, T obj2);
}

Sowie eine Methode sort:

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable<T> comp) {
    //sort the list
}

Kann ich aufrufen dieser Methode, und übergeben Sie einen lambda-Ausdruck als argument:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

Dass wird gut funktionieren.

Aber jetzt, wenn ich das interface nicht generisch, und die generische Methode:

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) {
}

Und dann aufrufen wie:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

Es nicht kompilieren. Es zeigt Fehler an der lambda-Ausdruck sagen:

"Target Methode ist generisch"

OK, wenn ich es kompiliert mit javac es zeigt folgenden Fehler:

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

Aus dieser Fehlermeldung, es scheint, wie compiler ist nicht in der Lage zu folgern, die Art der Argumente. Ist das der Fall? Wenn ja, dann warum ist es passiert wie diesem?

Ich habe versucht, verschiedene Möglichkeiten, gesucht über das internet. Dann fand ich diese JavaCodeGeeks Artikel, die zeigt ein Weg, so habe ich versucht:

sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));

was mal wieder nicht funktioniert, im Gegensatz zu dem, was dieser Artikel behauptet, dass es funktioniert. Könnte möglich sein, dass es früher in einigen anfänglichen baut.

Also meine Frage ist: gibt es eine Möglichkeit zu schaffen lambda-Ausdruck für eine generische Methode? Ich kann dies mithilfe einer Methode, Referenz, obwohl, durch die Schaffung einer Methode:

public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}

Klasse sagen SO, und übergeben Sie es als:

sort(list, SO::compare);

InformationsquelleAutor Rohit Jain | 2014-03-23

Schreibe einen Kommentar