java generics var local-variables java-10

java 10 var



¿Cómo se unen "var" y tipos sin procesar? (2)

Me encontré con una respuesta que sugiere utilizar ...

Ignoraría esa respuesta , porque como usted señala, usa tipos brutos y tipos de list como específicamente ArrayList . (Actualización: el respondedor editó su respuesta para agregar un tipo de elemento). En cambio:

List<AppropriateElementType> list = new ArrayList<>();

De acuerdo con la segunda respuesta que vinculó , var hará que el compilador deduzca un tipo de elemento desde el lado derecho si incluye <> , seleccionando el tipo más específico que pueda. In var list = new ArrayList<>(); Sin embargo, eso sería ArrayList<Object> , porque no tiene nada más específico que pueda elegir.

Pero , esto:

var list = new ArrayList();

... sin el <> , está utilizando un tipo sin ArrayList ( ArrayList ), no un tipo parametrizado con Object como el parámetro ( ArrayList<Object> ), que es diferente.

Si el uso de la list está suficientemente contenido (unas pocas líneas en un método), haberlo escrito ArrayList<X> lugar de List<X> puede ser aceptable (depende de su estilo de codificación), en cuyo caso:

var list = new ArrayList<AppropriateElementType>();

Pero en general prefiero codificar a la interfaz en lugar de a la clase concreta, incluso con los locales. Dicho esto, con los locales, es menos importante que con los miembros de la instancia, y var es conveniente.

Me encontré con una answer que sugiere utilizar

var list = new ArrayList();

Me sorprendió encontrar un tipo sin formato aquí, y simplemente me pregunto: ¿utiliza var <> "automáticamente?

(Mientras tanto, la respuesta se cambió para usar <String> , pero todavía siento curiosidad por los "principios" aquí)

Vi otras preguntas como this , pero todas usan el operador de diamante:

var list = new ArrayList<>();

Ahora simplemente me pregunto: ¿ var cambia la forma en que deberíamos (no) usar tipos en bruto? ¿O es esa sugerencia de dejar de lado <> simplemente una mala práctica?


Es legal usar tanto var como diamond , pero el tipo inferido cambiará:

var list = new ArrayList<>(); // DANGEROUS: infers as ArrayList<Object>

Para su inferencia, el diamond puede usar el tipo de objetivo (típicamente, el lado izquierdo de una declaración) o los tipos de argumentos de constructor. Si ninguno de los dos está presente, recurre al tipo más amplio aplicable, que a menudo es el Object 1 .

Tanto diamond métodos de diamond como con métodos genéricos, la información de tipo adicional puede ser proporcionada por argumentos reales al constructor o método, lo que permite inferir el tipo deseado 1 :

var list = List.of(BigInteger.ZERO); // OK: infers as List<BigInteger> var list = new ArrayList<String>( ); // OK: infers as ArrayList<String>

En vista de lo anterior, no recomiendo hacer lo siguiente (porque obtendrá el tipo ArrayList procesar):

var list = new ArrayList(); // DANGEROUS: infers as ArrayList

Conclusión:

  1. No utilice tipos brutos independientemente de la presencia o ausencia de var .
  2. Asegúrese de que los argumentos de método o constructor proporcionen suficiente información de tipo para que el tipo inferido coincida con su intención. De lo contrario, evite usar ambas var con diamond 1 .

1 - Directrices de estilo para la inferencia de tipo de variable local: G6. Tenga cuidado al usar var con diamante o métodos genéricos.