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
Generics Upper Bounded Wildcard
import java.util.ArrayList;
import java.util.List;
class GenericsWithWildCards
{
public static void main(String[] args)
{
List<Integer> integerList = new ArrayList<Integer>();
integerList.add(3);
integerList.add(5);
integerList.add(10);
print(integerList);
List<String> stringList = new ArrayList<String>();
stringList.add("A");
stringList.add("B");
stringList.add("C");
// print(stringList); // LINE A
}
// public static void print(List<Number> list) // LINE B
public static void print(List<? extends Number> list) // LINE C
{
for(Number input : list)
{
System.out.print(input +" ");
}
}
}
DESCRIPTIONHere uncomment the line at LINE B
and comment the line at LINE C
it 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 extends
keyword and the upper bound class
or interface
that 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.
THINGS TO TRY
- Create one more object for
Double
and invoke print()
method.
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
Generics Unbounded Wildcard
import java.util.ArrayList;
import java.util.List;
class GenericsWithWildCardsDemo
{
public static void main(String[] args)
{
List<Integer> integerList = new ArrayList<Integer>();
integerList.add(6);
integerList.add(3);
integerList.add(10);
print(integerList);
System.out.println("\n----------");
List<String> stringList = new ArrayList<String>();
stringList.add("A");
stringList.add("B");
stringList.add("C");
print(stringList);
}
public static void print(List<?> list)
{
for(Object input : list)
{
System.out.print(input +" ");
//list.add(input); // LINE A
}
}
}
OUTPUT6 3 10
----------
A B C
DESCRIPTIONIf we uncomment the line at LINE A
it gives compile time error since it does not allow to add anything to the list.
THINGS TO TRY
- Create one more instance for list of doubles and invoke the
print().
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
Generics Lower bounded Wildcard
import java.util.ArrayList;
import java.util.List;
class GenericsWithLowerBoundedWildCardsDemo
{
public static void main(String[] args)
{
List<Object> list = new ArrayList<Object>(); // LINE A
addIntegers(list); // LINE B
for(Object value : list)
{
System.out.print(value +" ");
}
}
public static void addIntegers(List<? super Integer> list)
{
for(int i = 1; i < 5; i++)
{
list.add(i);
}
}
}
DESCRIPTIONAt LINE A
we create an instance for object
list and at LINE B
we invoke addIntegers
method. It adds integers from 1 to 5. It supports to add to the list.
THINGS TO TRY
- Create one more method to add Doubles and invoke the method instead of
addIntegers
and print the values. Put lower bound class as Double
in the new method.