Java Reference
In-Depth Information
Unbounded Wildcards
As usual, let's start with an example. It will help you understand the need for as well as the use of wildcards in generic
types. Let's build a utility class for the
Wrapper
class. Call it
WrapperUtil
. Add a utility method called
printDetails()
to this class, which will take an object of the
Wrapper
<T> class. How should you define the argument of this method?
The following is the first attempt:
public class WrapperUtil {
public static void printDetails(Wrapper<Object> wrapper){
// More code goes here
}
}
Since your
printDetails()
method is supposed to print details about a
Wrapper
of any type,
Object
as parameter
type seemed to be more suitable. Let's use your new
printDetails()
method, as shown:
Wrapper<Object> objectWrapper = new Wrapper<Object>(new Object());
WrapperUtil.printDetails(objectWrapper); // OK
Wrapper<String> stringWrapper = new Wrapper<String>("Hello");
WrapperUtil.printDetails(stringWrapper); // A compile-time error
The compile-time error is as follows:
error: method printDetails in class WrapperUtil cannot be applied to given types;
WrapperUtil.printDetails(stringWrapper); // A compile-time error
^
required: Wrapper<Object>
found: Wrapper<String>
reason: argument mismatch; Wrapper<String> cannot be converted to Wrapper<Object>
1 error
You are able to call the
printDetails()
method with the
Wrapper<Object>
type, but not with the
Wrapper<String>
type because they are not assignment compatible, which is contradictory to what your intuition
tells you. To understand it fully, you need to know about the
wildcard type
in generics. A wildcard type is denoted by a
question mark, as in
<?>
. For a generic type, a wildcard type is what an
Object
type is for a raw type. You can assign a
generic of known type to a generic of wildcard type. Here is the sample code:
// Wrapper of String type
Wrapper<String> stringWrapper = new Wrapper<String>("Hi");
// You can assign a Wrapper<String> to Wrapper<?> type
Wrapper<?> wildCardWrapper = stringWrapper;
The question mark in a wildcard generic type (e.g., <?>) denotes an
unknown
type. When you declare a
parameterized type using a wildcard (means unknown) as a parameter type, it means that it does not know about its type.
// wildCardWrapper has unknown type
Wrapper<?> wildCardWrapper;
// Better to name it as an unknownWrapper
Wrapper<?> unknownWrapper;