Can anybody explain why we use ? in Collection generics.
As for example :
List<? extends Number> numberlist;
List<? super Integer> numberlist;
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
The wildcards introduce restrictions in how the collection can be used.
For example, with
List<? extends Number>, I can’t add new elements to the list. This is because all I know is that the list is some kind of subtype ofNumber, but I don’t know what that actual subtype is (so how could I know what to add?). For example, take the following code:This won’t compile because both of these method calls are legal:
What you can do is read elements from the list:
Calls to methods like
getwill return some kind ofNumber, we know that for a fact because of the? extends Number, so we can treat it like that for reading purposes.On the other hand,
List<? super Integer>has exactly the opposite result. I can no longer read from the list, but I can write to it. I know that whatever?is, it will definitely be a super-class ofInteger, so concrete types of the list will definitely acceptIntegervalues. For example:That code is completely legal. However, if you want to read from the list, the only way to do this is to use
Objectsince anything else requires casting (which requires knowing its concrete type):What’s Really Happening
Here’s what’s actually happening. When you specify
? extends Number, you’re making any method that takes elements as a parameter unusable. In fact, if you try to auto-complete code in Eclipse using Ctrl+Space on aList<? extends Number>, it showsnullas the parameters’ types in theaddmethods and the like. Meanwhile, all the methods that return elements are guaranteed to return at least some kind ofNumber, though you won’t know exactly which subclass ofNumberit might actually be.When you specify
? super Integer, you’re making any method that takes elements as a parameter guarantee that they’ll acceptIntegervalues (and sub-classes ofIntegeras well). This allows you to call methods likeaddsince you know they’ll acceptIntegertypes. Meanwhile, all methods that return elements are only guaranteed to return something, but we don’t know what, so all the methods that return elements are only guaranteed to returnObject.PECS is an excellent acronym to remember this, it means “Producer Extends, Consumer Supers”. This means that if you want your list to give you something, it’s a producer, and you should use
extends. If you want your list to accept things from you, it’s a consumer, so you usesuper. See this answer for more.But what if I have a wildcard with no bounds?
It does both!
<?>restricts you from calling methods that take the generic type as an argument and causes all the methods that return the generic type to returnObject. This is because we have no idea what the type is whatsoever. For example, all of these assignments into aList<?>are legal:And so on.