Por lo que puedo decir, este es un método genérico (a diferencia de un método de una clase genérica):

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)

Tengo curiosidad por saber cómo decide Java los tipos de parámetros para cualquier keyExtractor lambda que pase, dado que T está parametrizado.

Si hubiera alguna información adicional, como si T estuviera restringido a ser T super Z para un Z concreto, entonces tendría sentido que solo pueda pasar subclases de Z y, por lo tanto, dentro de keyExtractor lambda puedo escribir como si se ha pasado un objeto de clase Z.

Pero dado que no hay información disponible sobre T, ¿cómo funciona esto? ¿Decide en función del contexto de cómo se está utilizando la lambda devuelta por comparing? Estoy muy confundido, pero tal vez no entiendo completamente los genéricos y las lambdas.

Se agradecería cualquier aclaración, ¡gracias!

0
kng 27 ago. 2020 a las 03:17

1 respuesta

La mejor respuesta

Pero dado que no hay información disponible sobre T, ¿cómo funciona esto?

Si realmente no hay información disponible en T, entonces el valor predeterminado es Object, como cuando llama a comparing como una declaración independiente:

Comparator.comparing(x -> { ... });

El tipo de tiempo de compilación de x será Object.

Pero rara vez llamas a comparing así, ¿verdad? Por lo general, pasa su valor de retorno al método, o al menos lo asigna primero a una variable de un tipo conocido:

someMethod(Comparator.comparing(x -> { ... }));
// or
Comparator<SomeType> c = Comparator.comparing(x -> { ... });

En ambas situaciones, hay más información para determinar qué es T. Tenga en cuenta que el tipo de retorno de comparing es Comparator<T>, por lo que si someMethod arriba acepta un Comparator<SomeType>, el motor de inferencia de tipos puede determinar que T debe ser { {X6}} en ambos casos.

También tenga en cuenta que puede especificar el tipo de parámetro en una lambda, esto también ayuda a inferir T:

Comparator.comparing((SomeType x) -> { ... })
0
Sweeper 27 ago. 2020 a las 00:35