Java Generics
List Interface
Type Parameters
Programming Concepts
Java Collection Framework

Difference between List, List?, ListT, ListE, and ListObject

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In the Java programming language, understanding generics and their formulations is critical for writing robust and type-safe code. This article explores the differences between List, List<?>, List<T>, List<E>, and List<Object>, explaining their use cases, technical nuances, and providing examples where necessary.

Basic Concepts

Java Collections Framework

The Java Collections Framework (JCF) provides a set of classes and interfaces to handle collections of objects. The List interface is one of the primary interfaces defined in this framework. It represents an ordered collection, sometimes called a sequence. Lists can store duplicate elements, and elements can be accessed by their integer index.

Generics in Java

Introduced in Java 5, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. This allows you to catch more errors at compile time instead of at runtime, leading to more robust code.

The Differences

1. List

The List interface is a part of the Java Collections framework. However, using List without any generics is not recommended as it stores raw data types, bypassing the type-checking benefits that generics provide. This method requires casting when retrieving elements, increasing the possibility of runtime errors.

Example

java
1List rawList = new ArrayList();
2rawList.add("String");
3rawList.add(10); // Valid, but not type-safe
4String value = (String) rawList.get(0);

2. List<?>

The List<?> type is a wildcard type, often referred to as the "unbounded wildcard." It is read-only, meaning you cannot add new objects to this list except null. However, you can read elements and use them in a type-safe way.

Example

java
1public void printList(List<?> list) {
2    for (Object element : list) {
3        System.out.println(element);  // Safe read
4    }
5    // list.add("new element"); // Error: Cannot add to wildcard list
6}

3. List<T>

List<T> is a generic type where T is a type parameter that will be replaced by a specific type argument when an object is instantiated. It is a placeholder and does not commit to any specific type until specified.

Example

java
1class Box<T> {
2    private T t;
3
4    public void set(T t) {
5        this.t = t;
6    }
7
8    public T get() {
9        return t;
10    }
11}
12
13Box<Integer> integerBox = new Box<>();
14integerBox.set(new Integer(10));
15
16Box<String> stringBox = new Box<>();
17stringBox.set(new String("Java"));

4. List<E>

List<E> is similar to List<T> but is conventionally used in the context of collections where E stands for "Element." It represents a collection of Element type objects.

Example

java
1public class CustomList<E> {
2    private List<E> list = new ArrayList<>();
3
4    public void addElement(E element) {
5        list.add(element);
6    }
7
8    public E getElement(int index) {
9        return list.get(index);
10    }
11}

5. List<Object>

List<Object> represents a list that can contain elements of any type derived from the Object class. However, using this approach sacrifices type safety and the advantages of type-specific operations.

Example

java
1List<Object> objects = new ArrayList<>();
2objects.add("String");
3objects.add(10);
4for (Object obj : objects) {
5    System.out.println(obj);  // Outputs both types without error
6}

Comparison Table

TypeDescriptionUsage Safety
ListRaw type, not type-safe. Requires casting and may lead to runtime errors.Low
List<?>Unbounded wildcard. Read-only to certain extent; you cannot add elements except null. Can safely read objects as Object type.Medium
List<T>Generic type using type parameter T as a placeholder for any object type specified during instantiation. Supported in classes and methods.High
List<E>Generic type tailored for element collections, with E standing for "Element." Common in collections.High
List<Object>Accepts any object type (inherits from Object). Not recommended for specific type collections due to lack of type safety and generic capabilities.Low

Conclusion

In conclusion, generics in Java improve code safety, robustness, and readability. List, List<?>, List<T>, List<E>, and List<Object> serve different purposes and should be used according to your type safety requirements. Generally, prefer List<T> or List<E> to leverage the full potential of generics in Java. Understanding these distinctions will help you write more reliable and maintainable code.


Course illustration
Course illustration

All Rights Reserved.