Wildcards ?, extends, super In java
In the Java programming language, a wildcard (?) in a generics class method represents an unknown data type value method.

Wildcards in Java generics are primarily used when working with generic collection data types, and generics wildcards (?) are used when Java developers want a generics class method to accept data type elements with different class data type value parameters.
There are three main types of wildcards in Java generics.
- <?> — Unbounded generics wildcard.
- <? extends T> — Upper-bounded generics wildcard.
- <? super T> — Lower-bounded generics wildcard.
Unbounded wildcard <?> concept in Java.
Unbounded generics wildcard <?> in a Java program means any class data type element can be defined as a value in nature.
Example of Unbounded wildcard <?>.
List<?> list
Here, this can mean the List collection data type.
- List<String> for the String data type
- List<Integer> for the Integer data type
- List<Double> for the Double data type
- List<Employee> for a custom List data type
Example of an Unbounded wildcard.
import java.util.List;
import java.util.Arrays;
public class Main {
public static void preview(List<?> list) {
for (Object value : list) {
System.out.println(value);
}
}
public static void main(String[] args) {
List<String> comp_names =
Arrays.asList(“Vcanhelpsu”, “Vcandevelop”);
List<Integer> numerics =
Arrays.asList(98, 77, 11, 44, 88);
System.out.println(“*********The Company Names*********”);
preview(comp_names);
System.out.println(“\n*********The numerics*********”);
preview(numerics);
}
}
The key point of the unbounded wildcard.
In this example, with the List<?> unbounded wildcard data type, Java users cannot normally add a specific value because the actual data type declaration nature is unknown.
List<?> list = new ArrayList<String>();
list.add(“Vcanhelpsu”); //
But in this, Java users can read the class value as an object.
Object value = list.get(0);
Upper-bounded wildcard <? extends T> concept in Java.
Upper-bounded wildcard <? in Java program extends T> means that
the current Java program defines a class data type T or a subclass of T.
Example of an upper-bounded wildcard in Java.
List<? extends Number>
Here, “<?” can mean an upper-bounded wildcard.
- List<Integer> for the Integer data type class method
- List<Double> for the Double data type class method
- List<Float> for the Float data type class method
- List<Long> for the Long data type class method
Remember, these data types extend a Number value data element.
Example of an upper-bounded wildcard.
import java.util.List;
import java.util.Arrays;
public class Main {
public static void previewNumbers(
List<? extends Number> numbers) {
for (Number n : numbers) {
System.out.println(n);
}
}
public static void main(String[] args) {
List<Integer> integers =
Arrays.asList(444, 233, 989);
List<Double> doubles =
Arrays.asList(109.87, 123.34, 307.43);
System.out.println(“Integer Data type Values.”);
previewNumbers(integers);
System.out.println(“\nDouble Data type Values.”);
previewNumbers(doubles);
}
}
Why can’t we add in this example?
List<? extends Number > numbers =
new ArrayList<Integer>();
numbers.add(89); //
Here the Java compiler does not know the correct subtype. It can be a data type of either List<Double> or List<Integer>.
But it must be read securely.
Number n = numbers.get(0);
The main idea behind the upper-bounded wildcard.
<? extends T>
↓
Read the data value
↓
T or a subclass
The lower-bounded wildcard <? super T> concept in Java.
In a Java program, the lower-bounded wildcard <? super T> means that
T or a superclass of T is the value of the data type defined.
Example of a lower-bounded wildcard.
List<? super Integer>
Here, the lower-bounded wildcard can mean.
- List<Integer> for the integer data type class method
- List<Number> for the list numbers data type class method
- List<Object> for the list object data type class method
Example of a lower-bound wildcard.
public static void addNumbers(
List<? super Integer> list) {
list.add(7);
list.add(9);
list.add(11);
}
Usage in Java.
List<Integer> integers =
new ArrayList<>();
List<Number> numbers =
new ArrayList<>();
List<Object> objects =
new ArrayList<>();
addNumbers(integers);
addNumbers(numbers);
addNumbers(objects);
It is safe to add an Integer data type value here.
list.add(19); //
But when reading it, Java users can safely cast the value to an Object value only.
Object value = list.get(0);
Difference between extends and super in Java wildcards.
This is the most important element in Java wildcard usage.
extends
List<? extends Number>
Means:
Number variable
↑
Integer
Double data type
Float data type
Long data type
Java users can read values from it as Numbers, but cannot add values normally.
super
List<? super Integer>
Means:
Object
↑
Number
↑
Integer
Java users can safely add Integer values to it, but when reading, the safe type is Object.
PECS rule concept in Java wildcards.
There is a very easy rule to remember for multiple-use wildcards in the Java programming language.
PECS = Producer extends, Consumer super
Producer → Extends.
If a collection data type object in your source code creates/provides a value, use the extends method.
List<? extends Number>
Java users primarily read from it.
Consumer → super.
If a collection data type method in your program receives/takes a value from your source code, use the super method.
List<? super Integer>
You primarily add to it.
Comparison Of All Java Wildcard and Its Methods
| # | All popular java wildcard | Their meaning | Read as | Add allow/not |
| 1. | <?> – Unbounded generics wildcard | Support Any class data type | Object | Generally, no |
| 2. | <? extends T> – Upper-bounded generics wildcard. | Support only T or subclass | As T | Generally, no |
| 3. | <? super T> – Lower-bounded generics wildcard. | Support only T or superclass | As Object | T is safe |
In Java, you can read this with a simple memory trick.
- ? → Use this for any wildcard data type method.
- ? extends T → T or child → Use this for a READ data type method.
- ? super T → T or parent → Use this for a WRITE data type method.
Example.
List<? extends Number> wildcard.
Think of it as an unbounded generics wildcard.
“Give me a Number or its child; I want to read it.”
List<? super Integer>
Think of it as a lower-bounded generics wildcard.
“Give me an Integer or its parent; I want to add an Integer value.”
Example of a simple wildcard method in Java.
List<Integer> numbers =
Arrays.asList(1, 5, 7, 9);
List<? extends Number> readList = numbers;
Number n = readList.get(0);
Using extends here is correct because we are reading the data.
To write it in the proper order.
List<Integer> numbers =
new ArrayList<>();
List<? super Integer> writeList = numbers;
writeList.add(19);
writeList.add(77;
In this example, the super lower-bounded generics wildcard method is correct because we are adding/writing a value.
Conclusion of Wildcards ?, extends, super In Java.
<?> Unbounded generics wildcard.
→ This is used by Java users for methods of unknown data types in a class.
→ This can be read as a Java user object.
<? extends T> Upper-bounded generics wildcard.
→ This can be read by Java users as T or a subclass.
→ This is best for reading data type methods in a Java class.
→ This is a Java program data type producer.
<? super T> Lower-bounded generics wildcard.
→ This can be read by Java users as T or a superclass.
→ This is best for adding/writing values to a Java class.
→ This is a Java program data type producer is the consumer.
Remember this – PECS → Producer Extends, Consumer Super etc. in sequence or format.

