java una Método genérico tipo de referencia que especifica antes/después:: operador




metodos arraylist java (3)

Esto es lo que Intellij me cuenta sobre ellos:

BiPredicate<List<String>, String> contains1 = List<String>::contains;

Se pueden inferir argumentos de tipo explícito

BiPredicate<List<String>, String> contains2 = List::<String>contains;

Los argumentos de tipo son redundantes para la referencia de método no genérica

Si tuvieras que dividirlas en sus respectivas funciones lambda, creo que verías lo siguiente:

BiPredicate<List<String>, String> contains1 = (List<String> strings, String o) -> strings.contains(o);
BiPredicate<List<String>, String> contains2 = (strings, o) -> strings.<String>contains(o);

Como sabemos, las (List<String> strings, String o) se pueden reemplazar por (strings, o) y <String> en la segunda línea es innecesaria (ya que String#contains no es genérica), por lo que es seguro asumir que Ambas referencias de método son equivalentes.

¿Cuál es la diferencia entre las siguientes referencias de métodos,

BiPredicate<List<String>,String> contains1 = List<String>::contains;

BiPredicate<List<String>,String> contains2 = List::<String>contains;

BiPredicate<List<String>,String> contains3 = List<String>::<String>contains;

¿Los casos tienen nombres especiales? ¿Hay algún ejemplo similar al uso?


En:

BiPredicate<List<String>, String> contains2 = List::<String>contains;

<String> es un argumento de tipo para una lista no genérica. List.contains método 1 .

Mientras en:

BiPredicate<List<String>, String> contains1 = List<String>::contains;

<String> es un argumento de tipo para una List .

1 - En este caso particular, un argumento de tipo se ignora de acuerdo con JLS §15.12.2.1 :

Un método no genérico puede ser potencialmente aplicable a una invocación que proporciona argumentos de tipo explícito. En tal caso, los argumentos de tipo simplemente serán ignorados.


En primer lugar, se denomina testigo de tipo ( en el Tutorial oficial de Oracle ) o TypeArguments (en la Sec. 15.12 de JLS ) y está ayudando al compilador de manera efectiva con tales construcciones.

Un ejemplo:

private static void test(Callable<Object> call) {

}

private static void test(Runnable run) {

}

static class Gen<T> {

}

Y llámalo por test(Gen::new); (esto fallará, no importa por qué), pero el punto es que agrega un testigo de tipo para ayudar al compilador, así que esto funcionaría

test(Gen<String>::new);

Entonces, cuando escribe la List<String> , ha agregado un testigo de tipo para el tipo de destino - List que es; en el segundo caso, está agregando uno para el método que contains , pero no es genérico, por lo que se ignora.







method-reference