Difference between List, List<E>, List<Object>, and List<?> in java

Posted on

java-logoThis is very important topics in Generic to know the difference between List, List<?>,  List<E>, and List<Object>. Enabling Generic in you application code provides you a flexibility of code to work on different type of Data type and ensure to Type safety and easy to read.

In this example, we took a Collection Type i.e List but it can be any Collection Type i.e Set, LinkedList  and Map.



It’s a raw type and not type safe. It will generate a Runtime exception when casting is bad.

                List list = new ArrayList();
		list.add(new Object());
		// explicitly cast require here
		String s = (String) list.get(0);



It’s a parameterized type and ‘E‘ can be referred to any non-primitive type, any class type, any interface type, any array type, or even another type variable.

public <E> List<E> unmodifiableList(List<E> list) {
  return list;

E i.e element can be replaced with some concrete type like String,Integer,Number and other class, interface type.


It is a parameterized type of Object and It’s only allowed to add Object sub-type But does not allow to assign the sub-type reference into that list- means List<Object> instance will not accept the references of List<String> because List<String> is not a subtype of List<Object>, therefore compile generate a compiler errors.

List<Object> listOfObject = new ArrayList<Object>();
// OK
Object o = listOfObject.get(0);

List<String> listOfString = new ArrayList<String>();
//Error :- Type mismatch: cannot convert from List<String> to List<Object>
listOfObject = listOfString; // Compiler time error - Bad casting
List<Object> list1 = listOfString; // Compiler time error - Bad casting

List<Object> list2 = list1; // OK


‘?’ Question marks represented an unknown type. List<?> can be something that we don’t know right now. It’s also considered as READ-ONLY list where no any write operation will be performed only read operation is allowed like iteration over it, sizes of list and etc.

List<?> listOnUnknow = new ArrayList();
listOnUnknow.addAll("hello"); // Error because compiler don't know what type of value is going to store here.

We can do it like this :-

public static void reverse(List<?> list) {
     int size = list.size();
     if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
        for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
           swap(list, i, j);
     } else {
    ListIterator fwd = list.listIterator();
    ListIterator rev = list.listIterator(size);
    for (int i=0, mid=list.size()>>1; i<mid; i++) {
    Object tmp = fwd.next();



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s