5

I was wondering why is it not possible to call List<Number> not with List<Integer> even Integer is an extended class of the abstract class Number ? There is a logical error as I could call a Method with the parameter Number also with Integer.

public class Que
{

public void enterNumbers(List<Number> nummern)
{
    for (Number number : nummern)
    {
        System.out.println(number + "\n");
    }
}

public void enterNum(Number num)
{
    System.out.println("This is a number " + num);
}

public static void main(String[] args)
{
    Que que = new Que();

    Integer myInteger = new Integer(7);
    // possible (of course!)
    que.enterNum(myInteger);

    List<Integer> num = new ArrayList<Integer>();
    num.add(4);
    num.add(45);
    Integer inte = new Integer(333);

    num.add(inte);
    // not possible ! 
    que.enterNumbers(num);
}
}

To solve it I could work with List<?> or List<? extends Number>... so I don't need the solution I want to know the exact reason.

The only solution I could think of List is bind with Number as a new Type of Data Structure.

Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56
Fendrix
  • 556
  • 2
  • 11
  • 34
  • 1
    http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html – kosa Aug 29 '13 at 14:40
  • 3
    Think about it: `List` you can add a `Double`. `List` you cannot add a `Double`. – Sotirios Delimanolis Aug 29 '13 at 14:40
  • 5
    Because generics are not covariant like arrays. See [**this question**](http://stackoverflow.com/q/17384083/1348195) on more details. – Benjamin Gruenbaum Aug 29 '13 at 14:41
  • 2
    Take a look at: [Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p) – Pshemo Aug 29 '13 at 14:42
  • 1
    I don't get why people write proper answers as comments which cannot be ticked as correct?! – Thomas Aug 29 '13 at 14:50
  • You can find a good tutorial about it here . http://www.thejavageek.com/2013/08/27/generics-polymorphism-with-generics/ – Prasad Kharkar Aug 29 '13 at 14:55
  • If you want to call the method with a `List`, you could use a wildcard in the paramterized type instead: `List extends Number> nummern`, meaning a `List` of `Number` or some subtype of `Number` – Alderath Aug 29 '13 at 15:27

2 Answers2

11

Because you could e.g. add an instance of a different subclass of Number to List<Number>, e.g., an object of type Double, but obviously you shouldn't be allowed to add them to List<Integer>:

public void myMethod(List<Number> list) {
    list.add(new Double(5.5));
}

If you were allowed to call myMethod with an instance of List<Integer> this would result in a type clash when add is called.

Thomas
  • 17,016
  • 4
  • 46
  • 70
8

Generics are not co-varient like arrays. This is not allowed because of type erasure.

Consider classes Vehicle, Bike and Car.

If you make

public void addVehicle(List<Vehicle> vehicles){
    vehicles.add(new Car());
}
  • This is possible, because a Car is of type Vehicle, you can add a Car into Vehicle because it passes IS-A test.
  • But what if it was allowed to pass a List<Bike> to addVehicle(List<Vehicle> vehicles) ?

you would have added a Car to bike list. which is plain wrong. So generics doesn't allow this.

Read about Polymorphism with generics

Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56