Generic without type as method parameter - can't resolve it's field type

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











up vote
9
down vote

favorite
1












Let's consider a class:



public class Foo<T> 
public List<String> list = new ArrayList<>();



that I'm passing as a parameter to a method.




I have a problem understanding why here the type String isn't resolved:



public void test(Foo t) 
t.list.get(0).contains("test");



and the t.list is treated as List<Object> while here everything works just fine:



public void test(Foo<?> t) 
t.list.get(0).contains("test");



and t.list is List<String>.










share|improve this question





















  • Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
    – Michael
    2 hours ago










  • @Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
    – Jakubs
    2 hours ago






  • 1




    Possible duplicate of Compiler error on Java generic interface with a List<> method
    – Oleksandr
    1 hour ago










  • @Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
    – Jakubs
    1 min ago















up vote
9
down vote

favorite
1












Let's consider a class:



public class Foo<T> 
public List<String> list = new ArrayList<>();



that I'm passing as a parameter to a method.




I have a problem understanding why here the type String isn't resolved:



public void test(Foo t) 
t.list.get(0).contains("test");



and the t.list is treated as List<Object> while here everything works just fine:



public void test(Foo<?> t) 
t.list.get(0).contains("test");



and t.list is List<String>.










share|improve this question





















  • Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
    – Michael
    2 hours ago










  • @Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
    – Jakubs
    2 hours ago






  • 1




    Possible duplicate of Compiler error on Java generic interface with a List<> method
    – Oleksandr
    1 hour ago










  • @Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
    – Jakubs
    1 min ago













up vote
9
down vote

favorite
1









up vote
9
down vote

favorite
1






1





Let's consider a class:



public class Foo<T> 
public List<String> list = new ArrayList<>();



that I'm passing as a parameter to a method.




I have a problem understanding why here the type String isn't resolved:



public void test(Foo t) 
t.list.get(0).contains("test");



and the t.list is treated as List<Object> while here everything works just fine:



public void test(Foo<?> t) 
t.list.get(0).contains("test");



and t.list is List<String>.










share|improve this question













Let's consider a class:



public class Foo<T> 
public List<String> list = new ArrayList<>();



that I'm passing as a parameter to a method.




I have a problem understanding why here the type String isn't resolved:



public void test(Foo t) 
t.list.get(0).contains("test");



and the t.list is treated as List<Object> while here everything works just fine:



public void test(Foo<?> t) 
t.list.get(0).contains("test");



and t.list is List<String>.







java generics






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 hours ago









Jakubs

507




507











  • Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
    – Michael
    2 hours ago










  • @Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
    – Jakubs
    2 hours ago






  • 1




    Possible duplicate of Compiler error on Java generic interface with a List<> method
    – Oleksandr
    1 hour ago










  • @Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
    – Jakubs
    1 min ago

















  • Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
    – Michael
    2 hours ago










  • @Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
    – Jakubs
    2 hours ago






  • 1




    Possible duplicate of Compiler error on Java generic interface with a List<> method
    – Oleksandr
    1 hour ago










  • @Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
    – Jakubs
    1 min ago
















Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
– Michael
2 hours ago




Murat has answered your question, but you are aware that the <T> in Foo<T> is redundant, right?
– Michael
2 hours ago












@Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
– Jakubs
2 hours ago




@Michael yes, it was just for the purpose of giving an example where the T isn't used for the actual field type.
– Jakubs
2 hours ago




1




1




Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago




Possible duplicate of Compiler error on Java generic interface with a List<> method
– Oleksandr
1 hour ago












@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago





@Oleksandr in fact both questions are about the same problem but approach it from a different angle. Facing my problem and not knowing the solution I would be unable to understand the underlying reason behind both.
– Jakubs
1 min ago













2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










When using Foo t, t is a Raw Type so its non-static, non-inherited members, like the list in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):




To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.



More precisely, a raw type is defined to be one of:



  • . . .


  • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.




Just declare the list as static and the compiler will always assume it being a List of String (only for testing).



On the other side, Foo<?> is not a raw type, it is a generic type and consequently the list is also not considered a raw type.



And an advice later on that page:




The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




Note: Type Erasure and generated byte-code is the same in both cases...






share|improve this answer





























    up vote
    6
    down vote













    That's how Type Erasure works.




    Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.




    Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String and replace it with Object. That's why contains is not recognized since Object does not have that method call.



    By supplying <?> you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains since String has it.






    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%2f52403725%2fgeneric-without-type-as-method-parameter-cant-resolve-its-field-type%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
      3
      down vote



      accepted










      When using Foo t, t is a Raw Type so its non-static, non-inherited members, like the list in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):




      To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.



      More precisely, a raw type is defined to be one of:



      • . . .


      • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.




      Just declare the list as static and the compiler will always assume it being a List of String (only for testing).



      On the other side, Foo<?> is not a raw type, it is a generic type and consequently the list is also not considered a raw type.



      And an advice later on that page:




      The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




      Note: Type Erasure and generated byte-code is the same in both cases...






      share|improve this answer


























        up vote
        3
        down vote



        accepted










        When using Foo t, t is a Raw Type so its non-static, non-inherited members, like the list in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):




        To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.



        More precisely, a raw type is defined to be one of:



        • . . .


        • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.




        Just declare the list as static and the compiler will always assume it being a List of String (only for testing).



        On the other side, Foo<?> is not a raw type, it is a generic type and consequently the list is also not considered a raw type.



        And an advice later on that page:




        The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




        Note: Type Erasure and generated byte-code is the same in both cases...






        share|improve this answer
























          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          When using Foo t, t is a Raw Type so its non-static, non-inherited members, like the list in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):




          To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.



          More precisely, a raw type is defined to be one of:



          • . . .


          • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.




          Just declare the list as static and the compiler will always assume it being a List of String (only for testing).



          On the other side, Foo<?> is not a raw type, it is a generic type and consequently the list is also not considered a raw type.



          And an advice later on that page:




          The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




          Note: Type Erasure and generated byte-code is the same in both cases...






          share|improve this answer














          When using Foo t, t is a Raw Type so its non-static, non-inherited members, like the list in above code, are also raw types. Here the relevant part of the Java Language Specification (see above link):




          To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.



          More precisely, a raw type is defined to be one of:



          • . . .


          • A non-static member type of a raw type R that is not inherited from a superclass or superinterface of R.




          Just declare the list as static and the compiler will always assume it being a List of String (only for testing).



          On the other side, Foo<?> is not a raw type, it is a generic type and consequently the list is also not considered a raw type.



          And an advice later on that page:




          The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.




          Note: Type Erasure and generated byte-code is the same in both cases...







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 20 mins ago

























          answered 39 mins ago









          Carlos Heuberger

          23.4k85077




          23.4k85077






















              up vote
              6
              down vote













              That's how Type Erasure works.




              Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.




              Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String and replace it with Object. That's why contains is not recognized since Object does not have that method call.



              By supplying <?> you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains since String has it.






              share|improve this answer
























                up vote
                6
                down vote













                That's how Type Erasure works.




                Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.




                Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String and replace it with Object. That's why contains is not recognized since Object does not have that method call.



                By supplying <?> you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains since String has it.






                share|improve this answer






















                  up vote
                  6
                  down vote










                  up vote
                  6
                  down vote









                  That's how Type Erasure works.




                  Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.




                  Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String and replace it with Object. That's why contains is not recognized since Object does not have that method call.



                  By supplying <?> you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains since String has it.






                  share|improve this answer












                  That's how Type Erasure works.




                  Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.




                  Since your method accepts a raw type, the compiler applies the type erasure by erasing the type String and replace it with Object. That's why contains is not recognized since Object does not have that method call.



                  By supplying <?> you provide a bounded type and that will be used for the type erasure. There the compiler will recognize contains since String has it.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 2 hours ago









                  Murat Karagöz

                  12.7k32961




                  12.7k32961



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52403725%2fgeneric-without-type-as-method-parameter-cant-resolve-its-field-type%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      What does second last employer means? [closed]

                      List of Gilmore Girls characters

                      Confectionery