How do “var” and raw types come together?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
15
down vote

favorite
1












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?







share|improve this question

















  • 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















up vote
15
down vote

favorite
1












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?







share|improve this question

















  • 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













up vote
15
down vote

favorite
1









up vote
15
down vote

favorite
1






1





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?







share|improve this question













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?









share|improve this question












share|improve this question




share|improve this question








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 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













  • 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








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













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.






share|improve this answer



















  • 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


















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 Object1.



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:



  1. Don't use raw types irrespective of the presence or absence of var.

  2. Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both var with diamond1.


1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.






share|improve this answer























    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    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






























    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.






    share|improve this answer



















    • 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















    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.






    share|improve this answer



















    • 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













    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.






    share|improve this answer
















    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.







    share|improve this answer















    share|improve this answer



    share|improve this answer








    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 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













    • 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








    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













    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 Object1.



    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:



    1. Don't use raw types irrespective of the presence or absence of var.

    2. Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both var with diamond1.


    1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.






    share|improve this answer



























      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 Object1.



      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:



      1. Don't use raw types irrespective of the presence or absence of var.

      2. Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both var with diamond1.


      1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.






      share|improve this answer

























        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 Object1.



        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:



        1. Don't use raw types irrespective of the presence or absence of var.

        2. Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both var with diamond1.


        1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.






        share|improve this answer















        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 Object1.



        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:



        1. Don't use raw types irrespective of the presence or absence of var.

        2. Ensure that method or constructor arguments provide enough type information so that the inferred type matches your intent. Otherwise, avoid using both var with diamond1.


        1 - Style Guidelines for Local Variable Type Inference: G6. Take care when using var with diamond or generic methods.







        share|improve this answer















        share|improve this answer



        share|improve this answer








        edited Aug 8 at 11:50


























        answered Aug 6 at 11:33









        Oleksandr

        6,48033263




        6,48033263






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            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













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke