Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List<?> vs List<? extends Object> [duplicate]

Tags:

java

generics

Possible Duplicate:
What’s the difference between <?> and <? extends Object> in Java Generics?

I found that List<?>and List<? extends Object> act in the same way. As for me, there are no difference between them. If I am not right, can you explain me the difference?

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

public class TestClass {

static void func1(List<?> o, Object s) {
    o.add(null); // only null
    o.add(s); // wrong
    o.get(0);  // OK
}

static void func2(List<? extends Object> o, Object s) {
    o.add(null); // only null
    o.add(s); // wrong
    o.get(0); // OK
}

public static void main(String[] args) {
    func1(new ArrayList<String>(), new Integer(1));
    func2(new ArrayList<String>(), new Integer(1));

    List<? extends Object> list1 = new ArrayList<Object>();
    List<?> list2 = new ArrayList<Object>();

    List<? extends Object> list3 = new ArrayList<String>();
    List<?> list4 = new ArrayList<String>();
}
}
like image 888
Anton Kasianchuk Avatar asked Jan 15 '13 20:01

Anton Kasianchuk


People also ask

Are List <?> And List <? Extends Object the same?

There is no difference whatsoever. extends Object is redundant and assumed otherwise, just like writing class F extends Object .

What is the difference between List <?> And List Object?

Read carefully, the List<?> means you can assign any type of List to it and List<Object> means you can store any type of object into it.

What does <? Extends E mean in Java?

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.

What is difference between extends and super in generics?

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.


1 Answers

It is complicated...

For any type variable T, the spec says http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

Every type variable ... has a bound. If no bound is declared for a type variable, Object is assumed.

One would think that it's true for wildcard too, and ? should just be a shorthand for ? extends Object.

Yet searching through the spec, there is no evidence at all that a wildcard must have an upper bound (or lower bound). The "unbounded" ? is treated consistently distinctly from bounded wildcards.

We could deduce from subtyping rules, that List<?> and List<? extends Object> are subtypes of each other, i.e., they are basically the same type. (The deduction depends on the fact that E in interface List<E> has an implicit upper bound Object; but the rules do not require bounds on wildcards)

Nevertheless the spec treats the two differently. For example http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7 List<?> is a reifiable type, but List<? extends Object> is not, which means

    // ok
    List<?>[] xx = {};
    // fail
    List<? extends Object>[] yy = {};

    // ok
    boolean b1 = (y instanceof List<?>);
    // fail
    boolean b2 = (y instanceof List<? extends Object>);

I don't understand why though. It seems perfectly fine to say a wildcard must have an upper bound and a lower bound, default to Object and null type.

like image 118
irreputable Avatar answered Sep 17 '22 18:09

irreputable