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;
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
|
show 8 more comments
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
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
InsertingCollection<?>
in the place ofCollection
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 toCollection<?>
, it's closer toCollection<Object>
...
– Stobor
Apr 5 at 1:36
You can't insert anything into aCollection<?>
because you don't know what the correct type is.
– immibis
Apr 5 at 2:30
|
show 8 more comments
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
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
java generics
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
InsertingCollection<?>
in the place ofCollection
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 toCollection<?>
, it's closer toCollection<Object>
...
– Stobor
Apr 5 at 1:36
You can't insert anything into aCollection<?>
because you don't know what the correct type is.
– immibis
Apr 5 at 2:30
|
show 8 more comments
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
InsertingCollection<?>
in the place ofCollection
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 toCollection<?>
, it's closer toCollection<Object>
...
– Stobor
Apr 5 at 1:36
You can't insert anything into aCollection<?>
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
|
show 8 more comments
4 Answers
4
active
oldest
votes
The reason is quite simple:
You may read Object
s from a Collection<?>
the same way as from Collection
. But you can't add Object
s 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.
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 aboutT
, since you typed the Collection to<?>
).
– yshavit
Apr 5 at 7:27
4
Just to prevent the impression thatCollection<?>
was kind of immutable: you can addnull
to aCollection<?>
, further, you can pass aCollection<?>
to a generic method expecting aCollection<T>
, which then may add elements of typeT
, i.e. duplicates of elements already in the collection. As a practical example, you can invokeCollections.swap(list, ix1, ix2)
with aList<?>
. And, of course, removing elements always works. But you can not add an arbitraryObject
to it like with the raw typedCollection
.
– Holger
Apr 5 at 9:18
3
FWIW: I think Scala's syntax for existential types may also help to understand the meaning ofCollection<?>
. Scala's equivalent of this isCollection[_]
. And this is shorthand forCollection[T] forSome type T
. The latter should be understood as This is a collection of instances ofT
. 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
add a comment |
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.
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
add a comment |
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.
OP mentioned leaving the error in, and I agree with (both of) you.
– jpaugh
Apr 5 at 6:14
Well, ifCollection
was always treated likeCollection<?>
, 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 likenew 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
add a comment |
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
The reason is quite simple:
You may read Object
s from a Collection<?>
the same way as from Collection
. But you can't add Object
s 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.
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 aboutT
, since you typed the Collection to<?>
).
– yshavit
Apr 5 at 7:27
4
Just to prevent the impression thatCollection<?>
was kind of immutable: you can addnull
to aCollection<?>
, further, you can pass aCollection<?>
to a generic method expecting aCollection<T>
, which then may add elements of typeT
, i.e. duplicates of elements already in the collection. As a practical example, you can invokeCollections.swap(list, ix1, ix2)
with aList<?>
. And, of course, removing elements always works. But you can not add an arbitraryObject
to it like with the raw typedCollection
.
– Holger
Apr 5 at 9:18
3
FWIW: I think Scala's syntax for existential types may also help to understand the meaning ofCollection<?>
. Scala's equivalent of this isCollection[_]
. And this is shorthand forCollection[T] forSome type T
. The latter should be understood as This is a collection of instances ofT
. 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
add a comment |
The reason is quite simple:
You may read Object
s from a Collection<?>
the same way as from Collection
. But you can't add Object
s 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.
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 aboutT
, since you typed the Collection to<?>
).
– yshavit
Apr 5 at 7:27
4
Just to prevent the impression thatCollection<?>
was kind of immutable: you can addnull
to aCollection<?>
, further, you can pass aCollection<?>
to a generic method expecting aCollection<T>
, which then may add elements of typeT
, i.e. duplicates of elements already in the collection. As a practical example, you can invokeCollections.swap(list, ix1, ix2)
with aList<?>
. And, of course, removing elements always works. But you can not add an arbitraryObject
to it like with the raw typedCollection
.
– Holger
Apr 5 at 9:18
3
FWIW: I think Scala's syntax for existential types may also help to understand the meaning ofCollection<?>
. Scala's equivalent of this isCollection[_]
. And this is shorthand forCollection[T] forSome type T
. The latter should be understood as This is a collection of instances ofT
. 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
add a comment |
The reason is quite simple:
You may read Object
s from a Collection<?>
the same way as from Collection
. But you can't add Object
s 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.
The reason is quite simple:
You may read Object
s from a Collection<?>
the same way as from Collection
. But you can't add Object
s 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.
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 aboutT
, since you typed the Collection to<?>
).
– yshavit
Apr 5 at 7:27
4
Just to prevent the impression thatCollection<?>
was kind of immutable: you can addnull
to aCollection<?>
, further, you can pass aCollection<?>
to a generic method expecting aCollection<T>
, which then may add elements of typeT
, i.e. duplicates of elements already in the collection. As a practical example, you can invokeCollections.swap(list, ix1, ix2)
with aList<?>
. And, of course, removing elements always works. But you can not add an arbitraryObject
to it like with the raw typedCollection
.
– Holger
Apr 5 at 9:18
3
FWIW: I think Scala's syntax for existential types may also help to understand the meaning ofCollection<?>
. Scala's equivalent of this isCollection[_]
. And this is shorthand forCollection[T] forSome type T
. The latter should be understood as This is a collection of instances ofT
. 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
add a comment |
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 aboutT
, since you typed the Collection to<?>
).
– yshavit
Apr 5 at 7:27
4
Just to prevent the impression thatCollection<?>
was kind of immutable: you can addnull
to aCollection<?>
, further, you can pass aCollection<?>
to a generic method expecting aCollection<T>
, which then may add elements of typeT
, i.e. duplicates of elements already in the collection. As a practical example, you can invokeCollections.swap(list, ix1, ix2)
with aList<?>
. And, of course, removing elements always works. But you can not add an arbitraryObject
to it like with the raw typedCollection
.
– Holger
Apr 5 at 9:18
3
FWIW: I think Scala's syntax for existential types may also help to understand the meaning ofCollection<?>
. Scala's equivalent of this isCollection[_]
. And this is shorthand forCollection[T] forSome type T
. The latter should be understood as This is a collection of instances ofT
. 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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
OP mentioned leaving the error in, and I agree with (both of) you.
– jpaugh
Apr 5 at 6:14
Well, ifCollection
was always treated likeCollection<?>
, 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 likenew 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
add a comment |
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.
OP mentioned leaving the error in, and I agree with (both of) you.
– jpaugh
Apr 5 at 6:14
Well, ifCollection
was always treated likeCollection<?>
, 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 likenew 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
add a comment |
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.
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.
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, ifCollection
was always treated likeCollection<?>
, 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 likenew 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
add a comment |
OP mentioned leaving the error in, and I agree with (both of) you.
– jpaugh
Apr 5 at 6:14
Well, ifCollection
was always treated likeCollection<?>
, 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 likenew 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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Apr 4 at 11:12
T.J. Crowder
702k12412501343
702k12412501343
answered Apr 4 at 11:07
Ashishkumar SinghAshishkumar Singh
2,58911127
2,58911127
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 ofCollection
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 toCollection<?>
, it's closer toCollection<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