0
package test;

import java.util.ArrayList;
import java.util.List;

public class Test3 {

    public static void main(String[] args) {
        List<Number> number = new ArrayList<Number>();
        number.add(new Integer(10));
        number.add(new Double(10));
        List<Integer> inte = new ArrayList<Integer>();
        List<Number> numInt = new ArrayList<Integer>(); // compile error
        sum(number);
        sum(inte); // compile error
    }

    public static void sum(List<Number> n){

    }
}

I understand that List<Number> is not equal to List<Integer> from the Java Docs. And that Object is the parent class of both.

If you want to pass sub-types of Number, either do public static void sum(List<? extends Number> n) or public static <T extends Number> void(List<T> n)

My Question: List<Number> can contain a mix of Number Integer Double. Yet only the methods present in Number is accessible inside sum method. Even if I do List<? extends Number> instead of List<Number>, this is also giving me access only to methods of Number.

So,What usefulness/purpose is provided by considering List<Number> NOT equal to List<Integer>? (That is, how this restriction is useful?) Why do we need a separate syntax List<? extends Number>?

user104309
  • 690
  • 9
  • 20
  • 2
    I have no idea what logic brought you to think it would make any sense for them to be equal. By the same logic, _everything_ is equal to `List` and you can just stop using Generics. – Marko Topolnik Sep 30 '16 at 11:17
  • If `List` was regarded as a subtype of `List`, then the type system would be inconsistent - it would be possible to add objects to the list in a way that should not be possible. The linked duplicate question explains why. – Jesper Sep 30 '16 at 11:18
  • TL;DR: generics are realized with [Type erasure](https://docs.oracle.com/javase/tutorial/java/generics/erasure.html). To achieve what you want to do, use [Wildcards](https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html) and [PECS](http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super). – Turing85 Sep 30 '16 at 11:18
  • 2
    @Turing85 This is not about type erasure at all, but about the sanity of the type system. – Marko Topolnik Sep 30 '16 at 11:21
  • You can do `a.add(1.234)` to a `List` but not a `List` Also you can't write a generic sum of `List` unfortunately. – Peter Lawrey Sep 30 '16 at 11:38
  • @PeterLawrey What about `Number#doubleValue`? That would work pretty well. – Marko Topolnik Sep 30 '16 at 11:39
  • @MarkoTopolnik For `Long` not so well and `BigInteger`/`BigDecimal` not too good. If you have a `ComplexNumber` ... It would do a fine job otherwise. – Peter Lawrey Sep 30 '16 at 11:42
  • @MarkoTopolnik The logic (of course flawed and shallow) is that I only imagined the possibility to iterate over the list (that is, only 'get').I didn't expect a `Double` or `Float` or sub type of `Number` to be added inside `sum` method (which is equal to inserting a `Double` or a `Float` to the `List` variable `inte`). This is not a problem until we try to access the elements in `inte` expecting it to be an `Integer` but it could be any sub type of `Number` thus defeating the purpose of Generics. – user104309 Oct 01 '16 at 11:58
  • The reason I thought `List` and `List extends Number>` should exhibit the same behaviour (should be the same and hence the lengthier version is redundant) is again the same one - I only imagined to iterate over the list (that is,'get') and not to do 'add/insert/put' operation. In that case, both allows to iterate the elements in exactly the same way `for(Number num: n)` – user104309 Oct 01 '16 at 12:34

0 Answers0