2

Why can't I add an integer to this type of list, even though Integer extends Number>

List<? extends Number> numList = new ArrayList<Integer>(); 
Integer f = 12;
numList.add(f);
nbrooks
  • 18,126
  • 5
  • 54
  • 66
Sultan Zhumatayev
  • 535
  • 1
  • 9
  • 18
  • Does wildcards only for reading and using, but not for editing and adding? – Sultan Zhumatayev Oct 18 '16 at 05:38
  • 8
    Because the list could be a List, or a List, and you don't want an Integer to be stored into a List: that would ruin the type-safety of generics. – JB Nizet Oct 18 '16 at 05:40
  • How Could be the list of Double or BigDecimal if i cant add to it? – Sultan Zhumatayev Oct 18 '16 at 05:47
  • 1
    This will be helpful to answer your question. http://www.thejavageek.com/2013/08/28/generics-the-wildcard-operator/ – Prasad Kharkar Oct 18 '16 at 05:53
  • 1
    `List extends Number> numList = new ArrayList();`. A List extends Number> is a list of some type, that we don't know. All we know if that the tye is Number or extends Number. So you can be sure that all its elements are instances of Number, but you can't add anything to it because you don't know what the type is. – JB Nizet Oct 18 '16 at 05:55

4 Answers4

4

Have a look at this post on the PECS principle. Relevant quote:

You want to add things to the collection.
Then the list is a consumer, so you should use a Collection<? super Thing>.

In short, you'll want to use super rather than extends:

List<? super Number> numList = new ArrayList<>(); 
Integer f = 12;
numList.add(f);
Community
  • 1
  • 1
nbrooks
  • 18,126
  • 5
  • 54
  • 66
  • This is just equivalent to `List`, which throws away type safety. – Jim Garrison Oct 18 '16 at 06:14
  • 1
    @JimGarrison Nope, this is still type-safe. It provides compile-time type checking that anything being added to the list is a `Number`. – nbrooks Oct 18 '16 at 06:21
  • 1
    The link in this post was very helpful for me ,my question was all about producer consumer. – Sultan Zhumatayev Oct 18 '16 at 06:22
  • @nbrooks it may be type-safe on adding but when you retrieve elements an explicit cast is required to invoke other than `Object` methods on the element. – Jim Garrison Oct 18 '16 at 06:27
  • 1
    @JimGarrison In this case the list is treated as a consumer --- you're pushing data into it, rather than reading from it. In a method where this paradigm is being used it doesn't care about retrieving data from the list, so it uses the bounded wildcard to abstract that. – nbrooks Oct 18 '16 at 06:30
2

If you want to store any kind of number, you can simply do the following:

List<Number> numList = new ArrayList<Number>();
Pankaj Singhal
  • 15,283
  • 9
  • 47
  • 86
0

You need to use super keyword if you want to add elements to list.

List<? super Integer> numList = new ArrayList<Integer>(); 

and then do

 numList.add(10);
Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56
  • 1
    This is equivalent to `List` and discards type safety. When retrieving elements from the list you will not be able to invoke methods from `Number` or `Integer` without an explicit cast. – Jim Garrison Oct 18 '16 at 06:22
  • 1
    @JimGarrison This is a simplified example, so the use-cases where this can be useful aren't obvious from this snippet of code. The intention when using the `? super Type` paradigm is that you're not retrieving typed data from the list. To quote the post that I linked: *"If you are only pulling items from a generic collection, it is a producer and you should use `extends`; if you are only stuffing items in, it is a consumer and you should use `super`. If you do both with the same collection, you shouldn't use either `extends` or `super`."* – nbrooks Oct 18 '16 at 06:26
0

That List can be defined as List, List some other type also,In this case Compiler dont allow you to have Integer to be stored into a List: that would create problem in the type-safety features.

if you need You could use this

List<Number> numList = new ArrayList<Number>();
        Integer f = 100;
        numList.add(f);
Gautam
  • 3,707
  • 5
  • 36
  • 57