-3

I have the following code in JAVA :

List <? extends Number > l3=new List<Number>() ; // List not allowed ? why . and why arrayList is allowed here

Integer i=new Integer(5);

l3.add(i); // why we can not add i to l3 .

//------------- another thing :

    List <?> variablex;
  variablex.add(new Integer(5) ); // error ? so why ?

I am wondered why I have these errors at compile time ?

millimoose
  • 39,073
  • 9
  • 82
  • 134
Micha agus
  • 531
  • 2
  • 5
  • 12
  • 1
    Lets start from basic question: why do you want to use `List extends Number >` instead of `List` or maybe `List`? – Pshemo May 20 '14 at 00:01
  • This question seems like duplicate of combination of http://stackoverflow.com/questions/6810691/instantiating-a-list-in-java, http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface and http://stackoverflow.com/questions/5495383/java-generics-wildcard-question-list-extends-a. – Pshemo May 20 '14 at 00:23

2 Answers2

4

You must have a concrete implementation of List, such as ArrayList or LinkedList.

List <? extends Number> l3 = new ArrayList<Number>() ;

Whenever you have a wildcard as a generic type parameter for a reference variable, it could stand for anything. Here, with ? extends Number, it can be any subclass of Number (or Number) itself. It could be a List<Double>. To maintain type safety, the compiler must disallow a call to add with an Integer, because l3 could be a List<Double>, and you shouldn't be allowed to add an Integer to a List that may be of Doubles. With a List<?>, the wildcard could stand for anything.

List<?> l3 = new ArrayList<Number>();
// Later...
l3 = new LinkedList<MySpecialTypeYouDidntKnowAbout>();
// And then this doesn't work.
l3.add(new Integer(5));
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • "? extends Number" if it is not safe , then why it is allowed ? – Micha agus May 19 '14 at 23:50
  • @Michaagus *Adding* to it is not allowed. The expression itself is perfectly safe. – awksp May 19 '14 at 23:51
  • @Michaagus Generally, calling a method with a generic parameter such as `add`, on a generic class, results in type-unsafe code when the actual type of the variable is a wildcard. There are other uses of `?` or `? extends SomeClass`, such as when you don't have to call such a method as `add`. – rgettman May 19 '14 at 23:53
  • now List extends Number > l3=new ArrayList () ; Integer i=new Integer(5); // l3.add(i);// not allowed :( // it is Integer ? what should I use instead of Integer ,to allow it – Micha agus May 19 '14 at 23:54
  • @Michaagus You can call `add(anInteger)` on a `List`, a `List`, and a `List`. – rgettman May 19 '14 at 23:57
  • Why not with List extends Number > l3 – Micha agus May 20 '14 at 00:01
  • @Michaagus As I explained, the wildcard could stand for `Number` or any subtype, which may or may not be `Integer`. To the compiler, it could be `List`. For type safety reasons, the compiler doesn't let you add an `Integer` to something that could be a `List`. – rgettman May 20 '14 at 00:04
  • "*Why not with `List extends Number >`*" Lets say you have `List extends Fruits>`. This list can hold `ArrayList` or `ArrayList`, but list doesn't know which type of list it holds so you could end up adding `Apple` to list of Bananas. To prevent such possibility `method( extends SomeType> argument)` is blocked by compiler (unless `argument` is `null`). – Pshemo May 20 '14 at 00:06
  • You can also call `add(anInteger)` on a `List super Integer>`, although I fail to imagine any reason why you ever would. – Dawood ibn Kareem May 20 '14 at 00:09
1

List in an interface and you can't instantiate an interface.

ArrayList is an implementation of List interface and you can create object of class only.

Braj
  • 46,415
  • 5
  • 60
  • 76