What is a type parameter in a generic class?

Difference Between List<Object> and List<?> in Java

In Java, both List<Object> and List<?> are generic types, but they serve different purposes in terms of type flexibility and type safety. Let’s break down their differences:


1. List<Object>

Definition:

List<Object> means a list that can hold any object that is an instance of the Object class or its subclasses.

Key Characteristics:

  • Can store any type of object: Since every class in Java is a subclass of Object, a List<Object> can store any type of object (e.g., Integer, String, Double, custom objects, etc.).
  • Not type-safe for specific types: You can add any object to this list, but you lose type safety for specific use cases where you expect only certain types.

Example:

List<Object> list = new ArrayList<>();
list.add("String");
list.add(100); // Integer
list.add(10.5); // Double

  • Reading: When you retrieve elements from List<Object>, you know the type is Object, so you may need to cast it to the specific type you're expecting:

java String str = (String) list.get(0); Integer num = (Integer) list.get(1); * Type mismatch: If you intend the list to only store certain types (like String), then List<Object> is not appropriate, as it allows any type to be added.

Use Case:

List<Object> is used when you explicitly want to allow any type of object to be stored in the list and don't care about restricting the type of elements.


2. List<?> (Wildcard)

Definition:

List<?> is a wildcard generic type that represents a list of an unknown type. You cannot add any element to this list because the type is unknown, but you can still read from it.

Key Characteristics:

  • Can read from the list, but cannot add elements: Since the actual type of the elements is unknown, you can’t add anything to a List<?> (except null), but you can read elements as Object.
  • Type flexibility: It represents a list of some specific (but unknown) type, and you can pass a list of any type (List<String>, List<Integer>, etc.) to a method that accepts List<?>.

Example:

public void printList(List<?> list) {
    for (Object obj : list) {
        System.out.println(obj); // Can only read as Object
    }
}

  • Cannot add elements: You can't add items to List<?> because the actual type is not known:

java List<?> unknownList = new ArrayList<>(); unknownList.add("String"); // Compile-time error unknownList.add(100); // Compile-time error * Reading elements: You can retrieve elements from a List<?>, but they will be treated as Object because the specific type is not known:

java Object obj = unknownList.get(0);

Use Case:

List<?> is used when you want to write methods or work with lists in a type-safe way without caring about the specific type of the elements, such as in generic code or library APIs.


Summary of Differences:

\| Aspect \| List<Object> \| List<?> \|

\|----------------------\|-----------------------------------------\|-------------------------------------\|

\| What it Represents\| A list that can hold any type of object.\| A list of an unknown type. \|

\| Adding Elements \| You can add any object. \| Cannot add any elements (except null). \|

\| Reading Elements \| Elements are read as Object. \| Elements are read as Object. \|

\| Use Case \| When you want to store any type in the list. \| When you want type flexibility but won't modify the list. \|