S10L10 – Section wrap up with wildcards in Generics

Understanding Wildcards in Java Generics

Table of Contents

1. Introduction

Wildcards in Java Generics provide flexibility when dealing with parameterized types, allowing code to handle unknown types more effectively. In this article, we will explore the use of wildcards in Java Generics, focusing on the differences between the ? extends and ? super wildcards. We will also analyze a code example that demonstrates how wildcards can be applied in practical scenarios.

Key Points:

  • Importance of wildcards in managing different types in collections.
  • Overview of when to use ? extends and ? super for handling generics.

2. Understanding Wildcards in Java Generics

Wildcards in Java generics provide a means to handle parameterized types, allowing developers to write more flexible and reusable code. There are two primary types of wildcards:

  1. Upper-bounded Wildcard (? extends T): This wildcard is used when you want to work with types that are subclasses of a given type. It allows reading values but restricts adding new values.
  2. Lower-bounded Wildcard (? super T): This wildcard is used when you want to work with types that are superclasses of a given type. It allows adding values but restricts reading them as a specific type.
Wildcard Type Usage Example
? extends T Allows reading values of type T or its subclasses, but prevents writing List<? extends Number>
? super T Allows writing values of type T or its superclasses, but prevents reading List<? super Integer>

3. Code Explanation: Handling Wildcards in Java Generics

We will now break down the provided Java code, which demonstrates the use of the ? super wildcard in a method that accepts a list of Vehicle or any of its superclasses.

Key Concepts and Terminology

  • Class Vehicle: A simple class with an id field and an overridden toString() method for displaying the vehicle’s information.
  • Class Car: A subclass of Vehicle, which introduces an additional model field and overrides the toString() method to include the car’s model and vehicle ID.
  • Method display(List<? super Vehicle>): This method accepts a list of Vehicle or its superclasses using the ? super Vehicle wildcard. The method iterates over the list and prints each element. Here, ? super Vehicle ensures that any object in the list can be treated as a Vehicle.

Detailed Explanation:

  • Creating Objects: The main() method creates a list of Vehicle objects and adds several instances of Vehicle and Car. Since Car is a subclass of Vehicle, it can be added to the list of Vehicle.
  • Calling the display() Method: The display() method takes a list parameter using the wildcard ? super Vehicle, which ensures that the method can accept any list that holds Vehicle objects or any supertype of Vehicle.
  • Printing the List: Inside the display() method, we loop over the list using an enhanced for loop. Since the type is ? super Vehicle, we iterate over the elements as Object types and print them.

4. Output and Use Cases

Output of the Program

This output shows that both Vehicle and Car objects can be stored in the same list, and the display() method can print them, demonstrating the flexibility provided by wildcards.

When to Use Wildcards

Scenario Use Case
You want to read data from a list of objects that are all instances of a certain type or its subclasses Use ? extends
You want to write data into a list of objects that are instances of a certain type or its superclasses Use ? super

5. Conclusion

Wildcards in Java Generics are a powerful tool for handling collections of objects with varying types while maintaining type safety. By understanding when to use ? extends and ? super, developers can write more flexible, reusable code that works seamlessly with collections.