type parameter method generic example data java generics type-erasure unchecked raw-types

java - parameter - Advertencia de asignación no verificada



java method parameter generic class (2)

Cuando pretende aceptar una A<T> de cualquier tipo de T posible, pero no necesita la T , esto se expresa correctamente usando un comodín y escribiendo A<?> . Al hacerlo se eliminará la advertencia en su código:

public void processA(A<?> a) { Map<Integer, String> map = a.getMap(); }

Usar el tipo A desnudo no se trata de manera equivalente. Como se explica en la Especificación del lenguaje Java , los tipos sin procesar como este no están diseñados para ser usados ​​en el nuevo código:

La conversión sin marcar se usa para permitir una interoperación sin problemas del código heredado, escrito antes de la introducción de tipos genéricos, con bibliotecas que se han sometido a una conversión para usar la genéricoidad (un proceso que llamamos generación). En tales circunstancias (en particular, los clientes de Collections Framework en java.util), el código heredado usa tipos sin procesar (por ejemplo, Collection en lugar de Collection <String>). Las expresiones de tipos brutos se pasan como argumentos a los métodos de biblioteca que usan versiones parametrizadas de esos mismos tipos que los tipos de sus parámetros formales correspondientes.

No se puede demostrar que tales llamadas sean estáticamente seguras en el sistema de tipos que utiliza genéricos. Rechazar tales llamadas invalidaría grandes cuerpos de código existente e impediría que usen versiones más nuevas de las bibliotecas. Esto, a su vez, desalentaría a los vendedores de bibliotecas a aprovechar la genérica. Para evitar un giro no deseado de tales eventos, un tipo sin procesar puede convertirse en una invocación arbitraria de la declaración de tipo genérico a la que se refiere el tipo sin procesar. Si bien la conversión es errónea, se tolera como una concesión a la practicidad. En estos casos se emite una advertencia sin marcar.

Estoy usando Android Studio 1.1.0.

Esto no provoca ninguna advertencia:

public static class A { public Map<Integer, String> getMap() { return null; } } public static class B { public void processA(A a) { Map<Integer, String> map = a.getMap(); } }

Pero haz A genérico:

public static class A<T> { public Map<Integer, String> getMap() { return null; } }

Y esta línea:

Map<Integer, String> map = a.getMap();

recibe una advertencia ahora: "Unchecked assignment: ''java.util.Map to java.util.Map<java.lang.Integer, java.lang.String>'' .

Aunque la firma de getMap es totalmente independiente de T , y el código no es ambiguo con respecto a los tipos que contiene el Map .

Sé que puedo deshacerme de la advertencia reimplementando el processA siguiente manera:

public <T> void processA(A<T> a) { Map<Integer, String> map = a.getMap(); }

Pero ¿por qué tendría que hacer eso? ¿Qué importa T aquí?

Entonces, la pregunta es: ¿por qué el borrado de tipo no solo debe afectar a T (lo cual es comprensible? Si estoy pasando una instancia de A , T es una incógnita), sino también una firma genérica "codificada" como <Integer, String> ¿en este caso?


En tu segundo caso cuando lo haces:

public void processA(A a)

¿Qué quieres decir con A ? ¿Significa A<String> o A<List<String>> o qué? Es posible que no esté utilizando nada relacionado con el tipo de A , pero el compilador no sabe este hecho. Para el compilador, solo A es un signo de pánico.

En su caso, debido a que no necesita saber específicamente el tipo de A, puede:

public void processA(A<?> a) { Map<Integer, String> map = a.getMap(); }

Tener un tipo de argumento de A<?> Significa que no le importa específicamente el tipo de A y simplemente especifica un comodín. Para ti significa: cualquier objeto de A con cualquier tipo como lo haría su tipo genérico. En realidad, significa que no conoces el tipo. ¿Es inútil porque no puedes hacer nada relacionado con A de manera segura ? ¡Puede ser virtualmente cualquier cosa!

Pero según su cuerpo de método, tiene todo el sentido en el mundo usar A<?> Porque en ninguna parte del cuerpo necesita el tipo de A