I came across an answer that suggests to use
var list = new ArrayList();
I was surprised to find a raw type here, and I am simply wondering: does var
use the <>
"automatically?
( in the meantime, the answer was changed to use <String>
, but I am still curious about but "principles" here )
I saw other questions such as this, but they all use the diamond operator:
var list = new ArrayList<>();
Now I am simply wondering: does var
change how we should (not) be using raw types? Or is that suggestion to leave out <>
simply bad practice?
I came across an answer that suggests to use...
I would ignore that answer, because as you point out, it uses raw types and it types list
as specifically ArrayList
. (Update: The answerer edited their answer to add an element type.) Instead:
List<AppropriateElementType> list = new ArrayList<>();
According to the second answer you linked, var
will cause the compiler to infer an element type from the right-hand side if you include the <>
, picking the most specific type it can. In var list = new ArrayList<>();
that would be ArrayList<Object>
, though, because it doesn't have anything more specific it can choose.
But, this:
var list = new ArrayList();
...without the <>
, is using a raw type (ArrayList
), not a parameterized type with Object
as the parameter (ArrayList<Object>
), which is different.
If the use of list
is sufficiently contained (a few lines in a method), having it typed ArrayList<X>
rather than List<X>
may be acceptable (depends on your coding style), in which case:
var list = new ArrayList<AppropriateElementType>();
But generally I prefer to code to the interface rather than the concrete class, even with locals. That said, with locals, it is less important than with instance members, and var
is convenient.
It is legal to use both var
and diamond
, but the inferred type will change:
var list = new ArrayList<>(); // DANGEROUS: infers as ArrayList<Object>
For its inference, diamond
can use the target type (typically, the left-hand side of a declaration) or the types of constructor arguments. If neither is present, it falls back to the broadest applicable type, which is often Object
1.
With both diamond
and generic methods, additional type information can be provided by actual args to the constructor or method, allowing the intended type to be inferred1:
var list = List.of(BigInteger.ZERO); // OK: infers as List<BigInteger>
var list = new ArrayList<String>( ); // OK: infers as ArrayList<String>
In view of the above, I don't recommend to do the following (because you will get the raw ArrayList
type):
var list = new ArrayList(); // DANGEROUS: infers as ArrayList
var
.var
with diamond
1.1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With