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:
- No utilice tipos brutos independientemente de la presencia o ausencia de
var. - 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
varcondiamond1 .
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.