Wildcard Generic Types
Tags: java, programming, learning, beginners
Published: 2024-07-04 19:18:29

You can use unbounded wildcards, bounded wildcards, or lower-bound wildcards to specify a range for a generic type. What are wildcard generic types and why are they needed? The code below gives an example to
demonstrate the needs. The example defines a generic **max** method for finding the maximum in a stack of numbers (lines 15–25). The main method creates a stack of integer objects, adds three integers to the stack, and invokes the **max** method to find the maximum number in the stack.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i76v6zgmjg8t96yxv5z.png)

The program above has a compile error in line 11 because **intStack** is not an instance of **GenericStack<Number>**. Thus, you cannot invoke **max(intStack)**.

The fact is that **Integer** is a subtype of **Number**, but **GenericStack<Integer>** is not a subtype of **GenericStack<Number>**. To circumvent this problem, use wildcard generic types. A wildcard generic type has three forms: **?** and **? extends T**, as well as **? super T**, where **T** is a generic type.

The first form, **?**, called _an unbounded wildcard_, is the same as **? extends Object**. The second form, **? extends T**, called _a bounded wildcard_, represents **T** or a subtype of **T**. The third form, **? super T**, called _a lower-bound wildcard_, denotes **T** or a supertype of **T**.

You can fix the error by replacing line 15 in the code above as follows:

`public static double max(GenericStack<? extends Number> stack) {`

**<? extends Number>** is a wildcard type that represents **Number** or a subtype of **Number**, so it is legal to invoke **max(new GenericStack<Integer>())** or **max(new GenericStack<Double>())**.

The code below shows an example of using the **?** wildcard in the **print** method that prints objects in a stack and empties the stack. **<?>** is a wildcard that represents any object type. It is equivalent to **<? extends Object>**. What happens if you replace **GenericStack<?>** with **GenericStack<Object>**? It would be wrong to invoke **print(intStack)**, because **intStack** is not an instance of **GenericStack<Object>**. Please note that **GenericStack<Integer>** is not a subtype of **GenericStack<Object>**, even though **Integer** is a subtype of **Object**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30mvqo87ct4xepn4wu9s.png)

When is the wildcard **<? super T>** needed? Consider the example in the code below. The example creates a stack of strings in **stack1** (line 6) and a stack of objects in **stack2** (line 7), and invokes **add(stack1, stack2)** (line 11) to add the strings in **stack1** into **stack2**. **GenericStack<? super T>** is used to declare **stack2** in line 15. If **<? super T>** is replaced by **<T>**, a compile error will occur on **add(stack1, stack2)** in line 11, because **stack1**’s type is **GenericStack<String>** and **stack2**’s type is **GenericStack<Object>**. **<? super T>** represents type **T** or a supertype of **T**. **Object** is a supertype of **String**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cphlhahtvbmhn6ae4k3d.png)

This program will also work if the method header in lines 15 is modified as follows:

`public static <T> void add(GenericStack<? extends T> stack1,
 GenericStack<T> stack2)`

The inheritance relationship involving generic types and wildcard types is summarized in Figure below. In this figure, **A** and **B** represent classes or interfaces, and **E** is a generic type parameter.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qz3whfjvv6u99hm1y294.png)