Question mark (?) is the wildcard in generics and represents an unknown type. The wildcard can be used as the type of a parameter, field, or local variable and sometimes as a return type. We can’t use wildcards while invoking a generic method or instantiating a generic class.

Generics Upper Bounded Wildcard :
Upper bounded wildcards are used to relax the restriction on the type of variable in a method.

Generics Unbounded Wildcard :
Sometimes we have a situation where we want our generic method to work with all types, in this case unbounded wildcard can be used. Syntax : <? extends Object>

Generics Lower bounded Wildcard :
Suppose we want to add Integers to a list of integers in a method, we can keep the argument type as List<Integer>but it will be tied up with Integers whereas List<Number>and List<Object>can also hold integers, so we can use lower bound wildcard.
The following program explains the Generics Upper Bounded Wildcard

Here uncomment the line at LINE Band comment the line at LINE Cit gives compile time error. It won’t work with List of Integers or Doubles because we know that List<Integer> and List<Double> are not related, this is when upper bounded wildcard is helpful. We use generics wildcard with extendskeyword and the upper bound classor interfacethat will allow us to pass argument of upper bound or it’s subclasses types. Uncomment the LINE A it gives compile time error, since String class does not come under Number class.

The above program supports only numeric classes. If we have a situation where we want our generic method to be working with all types, unbounded wildcard can be used.
The following program explains the Generics Unbounded Wildcard

The above program does not support to add anything to the list. To overcome this we will go to the lower bounded wildcard.
The following program explains the functionality of Generics Lower bounded Wildcard