java generics parameters methods call

java - ¿Cuándo es útil una llamada de método parametrizado?



generics parameters (4)

Las llamadas de método parametrizadas son útiles cuando desea permitir diferentes tipos sin conversión. Por ejemplo, la clase auxiliar de Collections hace un uso extensivo de llamadas de método parametrizadas. Cuando desee crear una nueva colección genérica utilizando uno de sus métodos de ayuda, algunos ejemplos:

List<String> anEmptyStringList = Collections.<String>emptyList(); Set<Integer> unmodifiableCopy = Collections.<Integer>unmodifiableSet(originalSet);

Entonces, cuando quiere poder usar el tipo genérico en otro lugar, quiere usar esas llamadas de método. Evitan las advertencias del compilador cuando se usan genéricos.

Una llamada al método Java puede parametrizarse como en el siguiente código:

class Test { <T> void test() { } public static void main(String[] args) { new Test().<Object>test(); // ^^^^^^^^ } }

Descubrí que esto es posible desde el cuadro de diálogo de configuración del Eclipse Java Formatter y me pregunté si hay casos en que sea útil o necesario.

EDITAR

Basándome en la excelente respuesta de Arne, llegué a la siguiente conclusión:

Además de la seguridad de tipos mejorada, ya que el ejemplo de Arne ilustra una llamada de método parametrizada le permite especificar el tipo base común de los argumentos de los métodos que debe ser el tipo de los elementos contenedores. Este tipo normalmente es inferido automáticamente por el compilador al tipo de base común más específico. Al parametrizar la llamada al método, este comportamiento puede ser anulado. Es posible que se requiera una llamada a un método parametrizado si hay varios tipos comunes inferidos por el compilador.

El siguiente ejemplo demuestra ese comportamiento:

import java.util.Arrays; import java.util.List; class Test { public static void main(String[] args) { Integer a=new Integer(0); Long b=new Long(0); List<Object> listError=Arrays.asList(a, b); //error because Number&Comparable<?> is not Object List<Object> listObj=Arrays.<Object>asList(a, b); List<Number> listNum=Arrays.<Number>asList(a, b); List<Comparable<?>> listCmp=Arrays.<Comparable<?>>asList(a, b); } }

Este comportamiento se define en los párrafos 8.4.4 y 15.12.2.7 de la tercera edición de la especificación del lenguaje Java, pero no es fácil de entender.


Nunca he usado esto en la práctica, pero puedes imaginarte usarlo para seguridad de tipos. Considere el siguiente método:

<T> void method(T... items) { List<T> list = new ArrayList<T>(); for (T item : items) list.add(item); System.out.println(list); }

Puedes llamarlo así:

o.<Object>method("Blah", new Long(0)); o.<Number>method(new Integer(100), new Long(0));

Pero esto provocará un error de compilación:

o.<Number>method("String", new Long(0));

Por lo tanto, tiene un método genérico que es seguro para los tipos y se puede usar para cada Objeto, sin limitarse a una clase o interfaz particular.


Por ejemplo, cuando necesitas algún método universal para las comparaciones:

public static <T extends Comparable> T max(T one, T two) { if (one.compareTo(two) > 0) { return one; } else { return two; } }


Probablemente es más útil cuando toma una colección de algún tipo y devuelve algún subconjunto de esa colección.

<T> List<T> filter(Collection<? extends T> coll, Predicate<? super T> pred) { List<T> returnList = new ArrayList<T>(); for(T t : coll) { if(pred.matches(t)){ returnList.add(t); } } return returnList; }

Editar:

Más generalmente, es útil cuando desea devolver un tipo específico, o desea vincular los tipos de dos o más parámetros de una manera general.