Java Generic type : what is the difference between
(1) List <? extends Number> (2) List <T extends Number>
as per my understanding
(1) List <? extends Number>
is the Readonly List of "unknown" data type with super class "Number". we can read the element only but can not add
(2) List <T extends Number>
List of data type with super class "Number". we can read and add the elements into the list
Please see the below code example
class TestGen{ public static void main(String[] args) { double result = 0.0; List<Integer> intList = new ArrayList<Integer>(); intList.add(10); intList.add(20); intList.add(30); result = TestGen.sumOfList1(intList); System.out.println("Result=" + result); result = TestGen.sumOfList2(intList); System.out.println("Result=" + result); } public static double sumOfList1(List<? extends Number> list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s; } public static <T extends Number> double sumOfList2(List<T> list) { double s = 0.0; // getting error while trying to add new element // list<T> is not applicable for argument(Integer) : Why ? list.add(new Integer(40)); for (Number n : list) s += n.doubleValue(); return s; } }
When I am trying to add the Integer (or even Number object) into the sumOfList2 then getting the error. Please explain what is wrong here ?
extends Number> represents a list of Number or its sub-types such as Integer and Double. Lower Bounded Wildcards: List<? super Integer> represents a list of Integer or its super-types Number and Object.
6 Answers. Show activity on this post. Well there's no difference between the first two - they're just using different names for the type parameter ( E or T ). The third isn't a valid declaration - ? is used as a wildcard which is used when providing a type argument, e.g. List<?>
extends E means that it is also OK to add all members of a collection with elements of any type that is a subtype of E.
super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T .
Basic difference is if you use T extends Number
then you can refer to the type T
:list.add((T) new Integer(40));
Where as if you use ? extends Number
then you can not refer to the type, but you can still say:((List<Integer>)list).add((int) s);
In isolation, there isn't much difference. However, two instances of List<? extends Number>
in a single context are completely unrelated, while two instances of List<T extends Number>
in a single context refer to the same T
and the same interface.
public void addAll(List<? extends Number> to, List<? extends Number> from) { for (Number n: from) { to.add(n); } }
This method fails because n
can't be added to to
, and also failed because the member types of from
and to
can be completely different.
public <T> void addAll(List<T extends Number> to, List<T extends Number> from) { for (T n: from) { to.add(n); } }
This method compiles fine. It isn't necessary; Collections
has a better version, but it will run without error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With