How do âvarâ and raw types come together?
Clash Royale CLAN TAG#URR8PPP
up vote
15
down vote
favorite
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?
java generics var local-variables java-10
add a comment |Â
up vote
15
down vote
favorite
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?
java generics var local-variables java-10
5
FYI, the answer you've linked in your first sentence was edited by the author to add<String>
.
â T.J. Crowder
Aug 6 at 11:07
2
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
2
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
6
It's pretty simple. For avar
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.
â Brian Goetz
Aug 6 at 15:02
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10
add a comment |Â
up vote
15
down vote
favorite
up vote
15
down vote
favorite
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?
java generics var local-variables java-10
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?
java generics var local-variables java-10
edited Aug 7 at 3:54
nullpointer
28.3k1044115
28.3k1044115
asked Aug 6 at 11:00
GhostCat
79.6k1576133
79.6k1576133
5
FYI, the answer you've linked in your first sentence was edited by the author to add<String>
.
â T.J. Crowder
Aug 6 at 11:07
2
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
2
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
6
It's pretty simple. For avar
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.
â Brian Goetz
Aug 6 at 15:02
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10
add a comment |Â
5
FYI, the answer you've linked in your first sentence was edited by the author to add<String>
.
â T.J. Crowder
Aug 6 at 11:07
2
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
2
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
6
It's pretty simple. For avar
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.
â Brian Goetz
Aug 6 at 15:02
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10
5
5
FYI, the answer you've linked in your first sentence was edited by the author to add
<String>
.â T.J. Crowder
Aug 6 at 11:07
FYI, the answer you've linked in your first sentence was edited by the author to add
<String>
.â T.J. Crowder
Aug 6 at 11:07
2
2
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
2
2
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
6
6
It's pretty simple. For a
var
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.â Brian Goetz
Aug 6 at 15:02
It's pretty simple. For a
var
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.â Brian Goetz
Aug 6 at 15:02
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
29
down vote
accepted
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.
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how avar
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.
â Thorbjørn Ravn Andersen
Aug 6 at 11:45
add a comment |Â
up vote
8
down vote
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
Conclusion:
- Don't use raw types irrespective of the presence or absence of
var
. - Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both
var
withdiamond
1.
1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
29
down vote
accepted
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.
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how avar
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.
â Thorbjørn Ravn Andersen
Aug 6 at 11:45
add a comment |Â
up vote
29
down vote
accepted
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.
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how avar
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.
â Thorbjørn Ravn Andersen
Aug 6 at 11:45
add a comment |Â
up vote
29
down vote
accepted
up vote
29
down vote
accepted
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.
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.
edited Aug 6 at 12:08
answered Aug 6 at 11:04
T.J. Crowder
646k11011381236
646k11011381236
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how avar
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.
â Thorbjørn Ravn Andersen
Aug 6 at 11:45
add a comment |Â
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how avar
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.
â Thorbjørn Ravn Andersen
Aug 6 at 11:45
2
2
Being the answerer in the original question I just want to note that this was an off-hand reference to how a
var
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.â Thorbjørn Ravn Andersen
Aug 6 at 11:45
Being the answerer in the original question I just want to note that this was an off-hand reference to how a
var
expression would look in the context of the original answer and I forgot to move the type information from the left side (which was replaced by var) to the right side. Before I noticed this was commented upon and had a chance to fix it, this question was asked.â Thorbjørn Ravn Andersen
Aug 6 at 11:45
add a comment |Â
up vote
8
down vote
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
Conclusion:
- Don't use raw types irrespective of the presence or absence of
var
. - Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both
var
withdiamond
1.
1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
add a comment |Â
up vote
8
down vote
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
Conclusion:
- Don't use raw types irrespective of the presence or absence of
var
. - Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both
var
withdiamond
1.
1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
add a comment |Â
up vote
8
down vote
up vote
8
down vote
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
Conclusion:
- Don't use raw types irrespective of the presence or absence of
var
. - Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both
var
withdiamond
1.
1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
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
Conclusion:
- Don't use raw types irrespective of the presence or absence of
var
. - Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both
var
withdiamond
1.
1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.
edited Aug 8 at 11:50
answered Aug 6 at 11:33
Oleksandr
6,48033263
6,48033263
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51706066%2fhow-do-var-and-raw-types-come-together%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
5
FYI, the answer you've linked in your first sentence was edited by the author to add
<String>
.â T.J. Crowder
Aug 6 at 11:07
2
@SudhirOjha Same question to you: where in that question is any discussion regarding the usage of raw types in conjunction with var?
â GhostCat
Aug 6 at 11:56
2
Nice question. I guess this article by Brian and another one by Stuart could be good reads to get to know better about the styles and risks. Holger was pointing to the raw types as well, I would guess, he saw such a question coming somewhere down the line.
â nullpointer
Aug 6 at 13:20
6
It's pretty simple. For a
var
-declared local, we compute the type of the RHS as a standalone expression (and then perform a procedure called upward projection to project away capture variables.) If the RHS is raw, then the inferred type is a raw type. No magic.â Brian Goetz
Aug 6 at 15:02
@SudhirOjha I donâÂÂt think this is a duplicate of my question, as mine doesnâÂÂt really refer to raw types at all.
â Jacob G.
Aug 6 at 18:10