Why is Collection not simply treated as CollectionThe intersection of Java generics and Scala is…not going wellWhat is reflection and why is it useful?What is a serialVersionUID and why should I use it?Java generics type erasure: when and what happens?How do I address unchecked cast warnings?Why is subtracting these two times (in 1927) giving a strange result?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Why is char[] preferred over String for passwords?Why is it faster to process a sorted array than an unsorted array?Why is printing “B” dramatically slower than printing “#”?Generic return type upper bound - interface vs. class - surprisingly valid code

Add text to same line using sed

Is it possible to do 50 km distance without any previous training?

What does the "remote control" for a QF-4 look like?

Could an aircraft fly or hover using only jets of compressed air?

Is it unprofessional to ask if a job posting on GlassDoor is real?

What's that red-plus icon near a text?

How to determine what difficulty is right for the game?

How do I deal with an unproductive colleague in a small company?

LaTeX: Why are digits allowed in environments, but forbidden in commands?

Can I make popcorn with any corn?

What is a clear way to write a bar that has an extra beat?

Alternative to sending password over mail?

Arrow those variables!

Can a Cauchy sequence converge for one metric while not converging for another?

Did Shadowfax go to Valinor?

Theorems that impeded progress

Horror movie about a virus at the prom; beginning and end are stylized as a cartoon

How can bays and straits be determined in a procedurally generated map?

Accidentally leaked the solution to an assignment, what to do now? (I'm the prof)

What does "Puller Prush Person" mean?

Watching something be written to a file live with tail

How is it possible to have an ability score that is less than 3?

Why are electrically insulating heatsinks so rare? Is it just cost?

Client team has low performances and low technical skills: we always fix their work and now they stop collaborate with us. How to solve?



Why is Collection not simply treated as Collection>


The intersection of Java generics and Scala is…not going wellWhat is reflection and why is it useful?What is a serialVersionUID and why should I use it?Java generics type erasure: when and what happens?How do I address unchecked cast warnings?Why is subtracting these two times (in 1927) giving a strange result?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Why is char[] preferred over String for passwords?Why is it faster to process a sorted array than an unsorted array?Why is printing “B” dramatically slower than printing “#”?Generic return type upper bound - interface vs. class - surprisingly valid code






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








24















Consider the following API method taken from Shiro's org.apache.shiro.subject.PrincipalCollection interface but probably present in other libraries as well:



Collection fromRealm(String realmName);


Yes even nowadays there are still libraries that are using raw-types, probably to preserve pre Java 1.5 compatibility?!



If I now want to use this method together with streams or optionals like this:



principals.fromRealm(realmName).stream().collect(Collectors.toSet());


I get a warning about unchecked conversion and using raw types and that I should prefer using parameterized types.



Eclipse:




Type safety: The method collect(Collector) belongs to the raw type Stream. References to generic type Stream<T> should be parameterized




javac:




Note: GenericsTest.java uses unchecked or unsafe operations.




As I can't change the API method's signature to get rid of this warning I can either annotate with @SuppressWarnings("unchecked") or simply cast to Collection<?> like this:



((Collection<?>) principals.fromRealm(realmName)).stream().collect(Collectors.toSet());


As this cast of course always works I'm wondering why the compilers are not simply treating Collection as Collection<?> but warn about this situation. Adding the annotation or the cast doesn't improve the code a single bit, but decreases readability or might even shadow actual valid warnings about usage of unparameterized types.










share|improve this question



















  • 1





    The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

    – Martin Strejc
    yesterday












  • Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

    – ernest_k
    yesterday











  • I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

    – Murat Karagöz
    yesterday






  • 4





    Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

    – Stobor
    23 hours ago











  • You can't insert anything into a Collection<?> because you don't know what the correct type is.

    – immibis
    23 hours ago

















24















Consider the following API method taken from Shiro's org.apache.shiro.subject.PrincipalCollection interface but probably present in other libraries as well:



Collection fromRealm(String realmName);


Yes even nowadays there are still libraries that are using raw-types, probably to preserve pre Java 1.5 compatibility?!



If I now want to use this method together with streams or optionals like this:



principals.fromRealm(realmName).stream().collect(Collectors.toSet());


I get a warning about unchecked conversion and using raw types and that I should prefer using parameterized types.



Eclipse:




Type safety: The method collect(Collector) belongs to the raw type Stream. References to generic type Stream<T> should be parameterized




javac:




Note: GenericsTest.java uses unchecked or unsafe operations.




As I can't change the API method's signature to get rid of this warning I can either annotate with @SuppressWarnings("unchecked") or simply cast to Collection<?> like this:



((Collection<?>) principals.fromRealm(realmName)).stream().collect(Collectors.toSet());


As this cast of course always works I'm wondering why the compilers are not simply treating Collection as Collection<?> but warn about this situation. Adding the annotation or the cast doesn't improve the code a single bit, but decreases readability or might even shadow actual valid warnings about usage of unparameterized types.










share|improve this question



















  • 1





    The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

    – Martin Strejc
    yesterday












  • Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

    – ernest_k
    yesterday











  • I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

    – Murat Karagöz
    yesterday






  • 4





    Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

    – Stobor
    23 hours ago











  • You can't insert anything into a Collection<?> because you don't know what the correct type is.

    – immibis
    23 hours ago













24












24








24








Consider the following API method taken from Shiro's org.apache.shiro.subject.PrincipalCollection interface but probably present in other libraries as well:



Collection fromRealm(String realmName);


Yes even nowadays there are still libraries that are using raw-types, probably to preserve pre Java 1.5 compatibility?!



If I now want to use this method together with streams or optionals like this:



principals.fromRealm(realmName).stream().collect(Collectors.toSet());


I get a warning about unchecked conversion and using raw types and that I should prefer using parameterized types.



Eclipse:




Type safety: The method collect(Collector) belongs to the raw type Stream. References to generic type Stream<T> should be parameterized




javac:




Note: GenericsTest.java uses unchecked or unsafe operations.




As I can't change the API method's signature to get rid of this warning I can either annotate with @SuppressWarnings("unchecked") or simply cast to Collection<?> like this:



((Collection<?>) principals.fromRealm(realmName)).stream().collect(Collectors.toSet());


As this cast of course always works I'm wondering why the compilers are not simply treating Collection as Collection<?> but warn about this situation. Adding the annotation or the cast doesn't improve the code a single bit, but decreases readability or might even shadow actual valid warnings about usage of unparameterized types.










share|improve this question
















Consider the following API method taken from Shiro's org.apache.shiro.subject.PrincipalCollection interface but probably present in other libraries as well:



Collection fromRealm(String realmName);


Yes even nowadays there are still libraries that are using raw-types, probably to preserve pre Java 1.5 compatibility?!



If I now want to use this method together with streams or optionals like this:



principals.fromRealm(realmName).stream().collect(Collectors.toSet());


I get a warning about unchecked conversion and using raw types and that I should prefer using parameterized types.



Eclipse:




Type safety: The method collect(Collector) belongs to the raw type Stream. References to generic type Stream<T> should be parameterized




javac:




Note: GenericsTest.java uses unchecked or unsafe operations.




As I can't change the API method's signature to get rid of this warning I can either annotate with @SuppressWarnings("unchecked") or simply cast to Collection<?> like this:



((Collection<?>) principals.fromRealm(realmName)).stream().collect(Collectors.toSet());


As this cast of course always works I'm wondering why the compilers are not simply treating Collection as Collection<?> but warn about this situation. Adding the annotation or the cast doesn't improve the code a single bit, but decreases readability or might even shadow actual valid warnings about usage of unparameterized types.







java generics






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday







dpr

















asked yesterday









dprdpr

4,97311647




4,97311647







  • 1





    The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

    – Martin Strejc
    yesterday












  • Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

    – ernest_k
    yesterday











  • I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

    – Murat Karagöz
    yesterday






  • 4





    Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

    – Stobor
    23 hours ago











  • You can't insert anything into a Collection<?> because you don't know what the correct type is.

    – immibis
    23 hours ago












  • 1





    The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

    – Martin Strejc
    yesterday












  • Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

    – ernest_k
    yesterday











  • I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

    – Murat Karagöz
    yesterday






  • 4





    Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

    – Stobor
    23 hours ago











  • You can't insert anything into a Collection<?> because you don't know what the correct type is.

    – immibis
    23 hours ago







1




1





The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

– Martin Strejc
yesterday






The question mark type is a bit tricky. It can be anything, e.g. Collection<?> x; Collection<?> y; doesn't mean x can be cast to y, because it could be different. e. g. x = new ArrayList<String>() ; y=new ArrayList<Integer>() ;

– Martin Strejc
yesterday














Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

– ernest_k
yesterday





Inserting Collection<?> in the place of Collection would be tantamount to saying "don't worry about raw types, I've got you covered", whereas developers should actively avoid raw types.

– ernest_k
yesterday













I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

– Murat Karagöz
yesterday





I checked their source code and the date when it was first released. They were actually using generic types at that time, but not for that method for some reasons..

– Murat Karagöz
yesterday




4




4





Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

– Stobor
23 hours ago





Collection is not equivalent to Collection<?>, it's closer to Collection<Object>...

– Stobor
23 hours ago













You can't insert anything into a Collection<?> because you don't know what the correct type is.

– immibis
23 hours ago





You can't insert anything into a Collection<?> because you don't know what the correct type is.

– immibis
23 hours ago












4 Answers
4






active

oldest

votes


















47














The reason is quite simple:



You may read Objects from a Collection<?> the same way as from Collection. But you can't add Objects to a Collection<?> (The compiler forbids this) whereas to a Collection you can.



If after the release of Java 5 the compiler had translated every Collection to Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.






share|improve this answer




















  • 2





    To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

    – yshavit
    18 hours ago







  • 3





    Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

    – Holger
    16 hours ago












  • FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

    – Feuermurmel
    10 hours ago



















16














The major difference between raw type and unbounded wildcard <?> is that the latter is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type. Compiler won't allow you to add string and integer to the collection of wildcard type, but it will allow you to do this:



List raw = new ArrayList();
raw.add("");
raw.add(1);


Actually, in case of unbounded wildcard collections (List<?> wildcard = new ArrayList<String>()), you can't add anything at all to the list but null (from Oracle docs):




Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.







share|improve this answer




















  • 2





    "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

    – JimmyB
    yesterday












  • The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

    – John Bollinger
    yesterday



















4














This may be a bit too opinion-based for SO, but I believe the point of the compiler giving you a warning rather than silently assuming Collection<?> is that using raw types is something to avoid doing where possible. It's not an error because you can't always avoid it, but it's something that should be discouraged. A warning discourages using raw types, making you question whether a particular use was necessary. Silently treating it as Collection<?> doesn't.






share|improve this answer























  • OP mentioned leaving the error in, and I agree with (both of) you.

    – jpaugh
    19 hours ago











  • Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

    – Holger
    15 hours ago



















3














A use-case that I can think of as to why Collection is not considered as Collection<?> is let say we have a instance of ArrayList



Now if the instance is of type ArrayList<Integer> or ArrayList<Double> or ArrayList<String>, you can add that type only(type checking). ArrayList<?> is not equivalent to ArrayList<Object>.



But with only ArrayList, you can add object of any type. This may be one of the reason why compiler is not considering ArrayList as ArrayList<?> (type checking).



One more reason could be backward compatibility with Java version that didn't have generics.






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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    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%2f55514277%2fwhy-is-collection-not-simply-treated-as-collection%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    47














    The reason is quite simple:



    You may read Objects from a Collection<?> the same way as from Collection. But you can't add Objects to a Collection<?> (The compiler forbids this) whereas to a Collection you can.



    If after the release of Java 5 the compiler had translated every Collection to Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.






    share|improve this answer




















    • 2





      To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

      – yshavit
      18 hours ago







    • 3





      Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

      – Holger
      16 hours ago












    • FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

      – Feuermurmel
      10 hours ago
















    47














    The reason is quite simple:



    You may read Objects from a Collection<?> the same way as from Collection. But you can't add Objects to a Collection<?> (The compiler forbids this) whereas to a Collection you can.



    If after the release of Java 5 the compiler had translated every Collection to Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.






    share|improve this answer




















    • 2





      To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

      – yshavit
      18 hours ago







    • 3





      Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

      – Holger
      16 hours ago












    • FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

      – Feuermurmel
      10 hours ago














    47












    47








    47







    The reason is quite simple:



    You may read Objects from a Collection<?> the same way as from Collection. But you can't add Objects to a Collection<?> (The compiler forbids this) whereas to a Collection you can.



    If after the release of Java 5 the compiler had translated every Collection to Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.






    share|improve this answer















    The reason is quite simple:



    You may read Objects from a Collection<?> the same way as from Collection. But you can't add Objects to a Collection<?> (The compiler forbids this) whereas to a Collection you can.



    If after the release of Java 5 the compiler had translated every Collection to Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday









    Kilian Foth

    11.9k32847




    11.9k32847










    answered yesterday









    LinoLino

    11.3k22344




    11.3k22344







    • 2





      To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

      – yshavit
      18 hours ago







    • 3





      Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

      – Holger
      16 hours ago












    • FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

      – Feuermurmel
      10 hours ago













    • 2





      To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

      – yshavit
      18 hours ago







    • 3





      Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

      – Holger
      16 hours ago












    • FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

      – Feuermurmel
      10 hours ago








    2




    2





    To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

    – yshavit
    18 hours ago






    To add to this: Collection<?> is not "a Collection of any types." It's "a Collection of some type, but that type is unknown." That's why you can't add non-null objects to it: the compiler is trying to tell you that to add those objects, you'd have to know that the Collection's <T> is a superclass of those objects (whereas you don't actually know anything about T, since you typed the Collection to <?>).

    – yshavit
    18 hours ago





    3




    3





    Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

    – Holger
    16 hours ago






    Just to prevent the impression that Collection<?> was kind of immutable: you can add null to a Collection<?>, further, you can pass a Collection<?> to a generic method expecting a Collection<T>, which then may add elements of type T, i.e. duplicates of elements already in the collection. As a practical example, you can invoke Collections.swap(list, ix1, ix2) with a List<?>. And, of course, removing elements always works. But you can not add an arbitrary Object to it like with the raw typed Collection.

    – Holger
    16 hours ago














    FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

    – Feuermurmel
    10 hours ago






    FWIW: I think Scala's syntax for existential types may also help to understand the meaning of Collection<?>. Scala's equivalent of this is Collection[_]. And this is shorthand for Collection[T] forSome type T . The latter should be understood as This is a collection of instances of T. There is some specific type which is equal to T but which one is not known at this location in the code.

    – Feuermurmel
    10 hours ago














    16














    The major difference between raw type and unbounded wildcard <?> is that the latter is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type. Compiler won't allow you to add string and integer to the collection of wildcard type, but it will allow you to do this:



    List raw = new ArrayList();
    raw.add("");
    raw.add(1);


    Actually, in case of unbounded wildcard collections (List<?> wildcard = new ArrayList<String>()), you can't add anything at all to the list but null (from Oracle docs):




    Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.







    share|improve this answer




















    • 2





      "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

      – JimmyB
      yesterday












    • The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

      – John Bollinger
      yesterday
















    16














    The major difference between raw type and unbounded wildcard <?> is that the latter is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type. Compiler won't allow you to add string and integer to the collection of wildcard type, but it will allow you to do this:



    List raw = new ArrayList();
    raw.add("");
    raw.add(1);


    Actually, in case of unbounded wildcard collections (List<?> wildcard = new ArrayList<String>()), you can't add anything at all to the list but null (from Oracle docs):




    Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.







    share|improve this answer




















    • 2





      "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

      – JimmyB
      yesterday












    • The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

      – John Bollinger
      yesterday














    16












    16








    16







    The major difference between raw type and unbounded wildcard <?> is that the latter is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type. Compiler won't allow you to add string and integer to the collection of wildcard type, but it will allow you to do this:



    List raw = new ArrayList();
    raw.add("");
    raw.add(1);


    Actually, in case of unbounded wildcard collections (List<?> wildcard = new ArrayList<String>()), you can't add anything at all to the list but null (from Oracle docs):




    Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.







    share|improve this answer















    The major difference between raw type and unbounded wildcard <?> is that the latter is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type. Compiler won't allow you to add string and integer to the collection of wildcard type, but it will allow you to do this:



    List raw = new ArrayList();
    raw.add("");
    raw.add(1);


    Actually, in case of unbounded wildcard collections (List<?> wildcard = new ArrayList<String>()), you can't add anything at all to the list but null (from Oracle docs):




    Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday

























    answered yesterday









    Ondra K.Ondra K.

    970726




    970726







    • 2





      "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

      – JimmyB
      yesterday












    • The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

      – John Bollinger
      yesterday













    • 2





      "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

      – JimmyB
      yesterday












    • The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

      – John Bollinger
      yesterday








    2




    2





    "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

    – JimmyB
    yesterday






    "the [unbounded wildcard <?>] is type safe, that is, on a compile level, it checks whether the items in the collection are of the same type." - Huh?! This is in contradiction to the rest of your answer. - Or maybe not quite; one could say that it is type safe in that it disallows any objects to be put into a collection of <?>.

    – JimmyB
    yesterday














    The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

    – John Bollinger
    yesterday






    The compiler performs no checks at all on what is in a generic collection. Rather, it performs checks on the (declared) types of the arguments to its constructors and methods, and on the expectations of the types of its methods' return values.

    – John Bollinger
    yesterday












    4














    This may be a bit too opinion-based for SO, but I believe the point of the compiler giving you a warning rather than silently assuming Collection<?> is that using raw types is something to avoid doing where possible. It's not an error because you can't always avoid it, but it's something that should be discouraged. A warning discourages using raw types, making you question whether a particular use was necessary. Silently treating it as Collection<?> doesn't.






    share|improve this answer























    • OP mentioned leaving the error in, and I agree with (both of) you.

      – jpaugh
      19 hours ago











    • Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

      – Holger
      15 hours ago
















    4














    This may be a bit too opinion-based for SO, but I believe the point of the compiler giving you a warning rather than silently assuming Collection<?> is that using raw types is something to avoid doing where possible. It's not an error because you can't always avoid it, but it's something that should be discouraged. A warning discourages using raw types, making you question whether a particular use was necessary. Silently treating it as Collection<?> doesn't.






    share|improve this answer























    • OP mentioned leaving the error in, and I agree with (both of) you.

      – jpaugh
      19 hours ago











    • Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

      – Holger
      15 hours ago














    4












    4








    4







    This may be a bit too opinion-based for SO, but I believe the point of the compiler giving you a warning rather than silently assuming Collection<?> is that using raw types is something to avoid doing where possible. It's not an error because you can't always avoid it, but it's something that should be discouraged. A warning discourages using raw types, making you question whether a particular use was necessary. Silently treating it as Collection<?> doesn't.






    share|improve this answer













    This may be a bit too opinion-based for SO, but I believe the point of the compiler giving you a warning rather than silently assuming Collection<?> is that using raw types is something to avoid doing where possible. It's not an error because you can't always avoid it, but it's something that should be discouraged. A warning discourages using raw types, making you question whether a particular use was necessary. Silently treating it as Collection<?> doesn't.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered yesterday









    T.J. CrowderT.J. Crowder

    698k12312421338




    698k12312421338












    • OP mentioned leaving the error in, and I agree with (both of) you.

      – jpaugh
      19 hours ago











    • Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

      – Holger
      15 hours ago


















    • OP mentioned leaving the error in, and I agree with (both of) you.

      – jpaugh
      19 hours ago











    • Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

      – Holger
      15 hours ago

















    OP mentioned leaving the error in, and I agree with (both of) you.

    – jpaugh
    19 hours ago





    OP mentioned leaving the error in, and I agree with (both of) you.

    – jpaugh
    19 hours ago













    Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

    – Holger
    15 hours ago






    Well, if Collection was always treated like Collection<?>, in other words, raw types did not exist, there was no reason to discourage them. Then, insisting on <?> would be nonsense. Just like insisting on repeating types in constructor invocations like new ArrayList<VeryLongType>(). Since Java 7, you can use <> instead, but if this constructor type inference existed right from the start, even writing <> would be unnecessary.

    – Holger
    15 hours ago












    3














    A use-case that I can think of as to why Collection is not considered as Collection<?> is let say we have a instance of ArrayList



    Now if the instance is of type ArrayList<Integer> or ArrayList<Double> or ArrayList<String>, you can add that type only(type checking). ArrayList<?> is not equivalent to ArrayList<Object>.



    But with only ArrayList, you can add object of any type. This may be one of the reason why compiler is not considering ArrayList as ArrayList<?> (type checking).



    One more reason could be backward compatibility with Java version that didn't have generics.






    share|improve this answer





























      3














      A use-case that I can think of as to why Collection is not considered as Collection<?> is let say we have a instance of ArrayList



      Now if the instance is of type ArrayList<Integer> or ArrayList<Double> or ArrayList<String>, you can add that type only(type checking). ArrayList<?> is not equivalent to ArrayList<Object>.



      But with only ArrayList, you can add object of any type. This may be one of the reason why compiler is not considering ArrayList as ArrayList<?> (type checking).



      One more reason could be backward compatibility with Java version that didn't have generics.






      share|improve this answer



























        3












        3








        3







        A use-case that I can think of as to why Collection is not considered as Collection<?> is let say we have a instance of ArrayList



        Now if the instance is of type ArrayList<Integer> or ArrayList<Double> or ArrayList<String>, you can add that type only(type checking). ArrayList<?> is not equivalent to ArrayList<Object>.



        But with only ArrayList, you can add object of any type. This may be one of the reason why compiler is not considering ArrayList as ArrayList<?> (type checking).



        One more reason could be backward compatibility with Java version that didn't have generics.






        share|improve this answer















        A use-case that I can think of as to why Collection is not considered as Collection<?> is let say we have a instance of ArrayList



        Now if the instance is of type ArrayList<Integer> or ArrayList<Double> or ArrayList<String>, you can add that type only(type checking). ArrayList<?> is not equivalent to ArrayList<Object>.



        But with only ArrayList, you can add object of any type. This may be one of the reason why compiler is not considering ArrayList as ArrayList<?> (type checking).



        One more reason could be backward compatibility with Java version that didn't have generics.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited yesterday









        T.J. Crowder

        698k12312421338




        698k12312421338










        answered yesterday









        Ashishkumar SinghAshishkumar Singh

        2,49411127




        2,49411127



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55514277%2fwhy-is-collection-not-simply-treated-as-collection%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

            Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

            Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form