Why is Collection not simply treated as Collection Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!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

Why can't fire hurt Daenerys but it did to Jon Snow in season 1?

One-one communication

What did Turing mean when saying that "machines cannot give rise to surprises" is due to a fallacy?

The Nth Gryphon Number

Problem with display of presentation

Is this Kuo-toa homebrew race balanced?

Why are current probes so expensive?

Is a copyright notice with a non-existent name be invalid?

How to name indistinguishable henchmen in a screenplay?

How do I say "this must not happen"?

How do I find my Spellcasting Ability for my D&D character?

Why is there so little support for joining EFTA in the British parliament?

Plotting a Maclaurin series

What should one know about term logic before studying propositional and predicate logic?

Found this skink in my tomato plant bucket. Is he trapped? Or could he leave if he wanted?

Do i imagine the linear (straight line) homotopy in a correct way?

What is a more techy Technical Writer job title that isn't cutesy or confusing?

Why are two-digit numbers in Jonathan Swift's "Gulliver's Travels" (1726) written in "German style"?

My mentor says to set image to Fine instead of RAW — how is this different from JPG?

How does the body cool itself in a stillsuit?

Besides transaction validation, are there any other uses of the Script language in Bitcoin

How to infer difference of population proportion between two groups when proportion is small?

By what mechanism was the 2017 UK General Election called?

What is "Lambda" in Heston's original paper on stochastic volatility models?



Why is Collection not simply treated as Collection>



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!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;








33















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
    Apr 4 at 11:06












  • 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
    Apr 4 at 11:08











  • 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
    Apr 4 at 11:19






  • 4





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

    – Stobor
    Apr 5 at 1:36











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

    – immibis
    Apr 5 at 2:30

















33















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
    Apr 4 at 11:06












  • 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
    Apr 4 at 11:08











  • 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
    Apr 4 at 11:19






  • 4





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

    – Stobor
    Apr 5 at 1:36











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

    – immibis
    Apr 5 at 2:30













33












33








33


1






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 Apr 4 at 11:23







dpr

















asked Apr 4 at 11:00









dprdpr

5,05811847




5,05811847







  • 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
    Apr 4 at 11:06












  • 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
    Apr 4 at 11:08











  • 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
    Apr 4 at 11:19






  • 4





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

    – Stobor
    Apr 5 at 1:36











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

    – immibis
    Apr 5 at 2:30












  • 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
    Apr 4 at 11:06












  • 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
    Apr 4 at 11:08











  • 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
    Apr 4 at 11:19






  • 4





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

    – Stobor
    Apr 5 at 1:36











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

    – immibis
    Apr 5 at 2:30







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
Apr 4 at 11:06






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
Apr 4 at 11:06














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
Apr 4 at 11:08





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
Apr 4 at 11:08













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
Apr 4 at 11:19





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
Apr 4 at 11:19




4




4





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

– Stobor
Apr 5 at 1:36





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

– Stobor
Apr 5 at 1:36













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

– immibis
Apr 5 at 2:30





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

– immibis
Apr 5 at 2:30












4 Answers
4






active

oldest

votes


















61














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




















  • 3





    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
    Apr 5 at 7:27







  • 4





    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
    Apr 5 at 9:18







  • 3





    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
    Apr 5 at 15:18



















19














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
    Apr 4 at 15:29







  • 1





    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
    Apr 4 at 21:53



















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
    Apr 5 at 6:14











  • 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
    Apr 5 at 9:39



















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









    61














    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




















    • 3





      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
      Apr 5 at 7:27







    • 4





      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
      Apr 5 at 9:18







    • 3





      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
      Apr 5 at 15:18
















    61














    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




















    • 3





      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
      Apr 5 at 7:27







    • 4





      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
      Apr 5 at 9:18







    • 3





      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
      Apr 5 at 15:18














    61












    61








    61







    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 Apr 4 at 21:16









    Kilian Foth

    11.9k32847




    11.9k32847










    answered Apr 4 at 11:05









    LinoLino

    11.8k22344




    11.8k22344







    • 3





      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
      Apr 5 at 7:27







    • 4





      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
      Apr 5 at 9:18







    • 3





      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
      Apr 5 at 15:18













    • 3





      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
      Apr 5 at 7:27







    • 4





      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
      Apr 5 at 9:18







    • 3





      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
      Apr 5 at 15:18








    3




    3





    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
    Apr 5 at 7:27






    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
    Apr 5 at 7:27





    4




    4





    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
    Apr 5 at 9:18






    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
    Apr 5 at 9:18





    3




    3





    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
    Apr 5 at 15:18






    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
    Apr 5 at 15:18














    19














    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
      Apr 4 at 15:29







    • 1





      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
      Apr 4 at 21:53
















    19














    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
      Apr 4 at 15:29







    • 1





      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
      Apr 4 at 21:53














    19












    19








    19







    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 Apr 4 at 11:20

























    answered Apr 4 at 11:08









    Ondra K.Ondra K.

    1,0811926




    1,0811926







    • 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
      Apr 4 at 15:29







    • 1





      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
      Apr 4 at 21:53













    • 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
      Apr 4 at 15:29







    • 1





      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
      Apr 4 at 21:53








    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
    Apr 4 at 15:29






    "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
    Apr 4 at 15:29





    1




    1





    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
    Apr 4 at 21:53






    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
    Apr 4 at 21:53












    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
      Apr 5 at 6:14











    • 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
      Apr 5 at 9:39
















    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
      Apr 5 at 6:14











    • 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
      Apr 5 at 9:39














    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 Apr 4 at 11:05









    T.J. CrowderT.J. Crowder

    702k12412501343




    702k12412501343












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

      – jpaugh
      Apr 5 at 6:14











    • 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
      Apr 5 at 9:39


















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

      – jpaugh
      Apr 5 at 6:14











    • 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
      Apr 5 at 9:39

















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

    – jpaugh
    Apr 5 at 6:14





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

    – jpaugh
    Apr 5 at 6:14













    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
    Apr 5 at 9:39






    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
    Apr 5 at 9:39












    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 Apr 4 at 11:12









        T.J. Crowder

        702k12412501343




        702k12412501343










        answered Apr 4 at 11:07









        Ashishkumar SinghAshishkumar Singh

        2,58911127




        2,58911127



























            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

            Adding axes to figuresAdding axes labels to LaTeX figuresLaTeX equivalent of ConTeXt buffersRotate a node but not its content: the case of the ellipse decorationHow to define the default vertical distance between nodes?TikZ scaling graphic and adjust node position and keep font sizeNumerical conditional within tikz keys?adding axes to shapesAlign axes across subfiguresAdding figures with a certain orderLine up nested tikz enviroments or how to get rid of themAdding axes labels to LaTeX figures

            Luettelo Yhdysvaltain laivaston lentotukialuksista Lähteet | Navigointivalikko

            Gary (muusikko) Sisällysluettelo Historia | Rockin' High | Lähteet | Aiheesta muualla | NavigointivalikkoInfobox OKTuomas "Gary" Keskinen Ancaran kitaristiksiProjekti Rockin' High