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
, aList<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 isObject
, 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<?>
(exceptnull
), but you can read elements asObject
. - 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 acceptsList<?>
.
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. \|