Supposons que j'ai une interface générique:
interface MyComparable<T extends Comparable<T>> {
public int compare(T obj1, T obj2);
}
Et une méthode sort
:
public static <T extends Comparable<T>>
void sort(List<T> list, MyComparable<T> comp) {
// sort the list
}
Je peux invoquer cette méthode et passer une expression lambda comme argument:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Cela fonctionnera très bien.
Mais maintenant, si je rends l'interface non générique et la méthode générique:
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) {
}
Et puis invoquez ceci comme:
List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
Il ne compile pas. Il montre une erreur à l'expression lambda en disant:
"La méthode cible est générique"
OK, lorsque je l'ai compilé en utilisant javac
, il affiche l'erreur suivante:
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
À partir de ce message d'erreur, il semble que le compilateur ne soit pas en mesure de déduire les arguments de type. Est-ce le cas? Si oui, pourquoi cela se passe-t-il ainsi?
J'ai essayé différentes méthodes, j'ai cherché sur Internet. Ensuite, j'ai trouvé cet article JavaCodeGeeks , qui montre un moyen, alors j'ai essayé:
sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
qui encore une fois ne fonctionne pas, contrairement à ce que cet article prétend que cela fonctionne. Peut-être qu'il fonctionnait dans certaines versions initiales.
Ma question est donc la suivante: existe-t-il un moyen de créer une expression lambda pour une méthode générique? Je peux le faire en utilisant une référence de méthode, en créant une méthode:
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
return obj1.compareTo(obj2);
}
dans une classe, dites SO
et passez-le comme:
sort(list, SO::compare);