When no specific knowledge of the value of a type parameter is needed, it can be replaced by a wildcard. The wildcard alone, represented by a question mark, takes the value of the default bound of the corresponding formal type parameter, which is Object in following example:
void printElements(List<?> myList) { ... }
A wildcard might include an upper bound, which states that the value of the type parameter must be equal to, or a descendent of the bound, as in the following:
void addAll(Collection<? extends E>) { ... {
A wildcard may alternately specify a lower bound, as in the following:
void addAll(Collection<? super E>) { ... {
example of upperbound wildcard
It is possible to set the upper bound of the wildcard like this:
List<? extends Vehicle> vehicles = new ArrayList<? extends Vehicle>();
In this example I have specified the upper bound to be the class Vehicle. I can now define the processElements() method like this:
public void processElements(List<? extends Vehicle> elements){
for(Vehicle o : elements){
System.out.println(o);
}
}
As you can see it is now safe to cast each element in the list to a Vehicle, as it is done by the new for loop inside the method.
Furthermore, it is now safe to call the method using a List<Car> instance, provided that Car extends Vehicle. Here is an example:
List<Car> elements = new ArrayList<Car>
// ... add Car elements to the list.
processElements(elements);
But, even when using a wildcard with an upper bound it is not safe to write to the List. After all, a Car is always a Vehicle, but a Vehicle is not always a Car.
By using wildcard, Well, we got:
1) A way to specify that a collection can contain any type.
2) A way to specify that a collection can contain any subtype of X.
3) ... and this at the price of not being able to write to such a collection.
void printElements(List<?> myList) { ... }
A wildcard might include an upper bound, which states that the value of the type parameter must be equal to, or a descendent of the bound, as in the following:
void addAll(Collection<? extends E>) { ... {
A wildcard may alternately specify a lower bound, as in the following:
void addAll(Collection<? super E>) { ... {
example of upperbound wildcard
It is possible to set the upper bound of the wildcard like this:
List<? extends Vehicle> vehicles = new ArrayList<? extends Vehicle>();
In this example I have specified the upper bound to be the class Vehicle. I can now define the processElements() method like this:
public void processElements(List<? extends Vehicle> elements){
for(Vehicle o : elements){
System.out.println(o);
}
}
As you can see it is now safe to cast each element in the list to a Vehicle, as it is done by the new for loop inside the method.
Furthermore, it is now safe to call the method using a List<Car> instance, provided that Car extends Vehicle. Here is an example:
List<Car> elements = new ArrayList<Car>
// ... add Car elements to the list.
processElements(elements);
But, even when using a wildcard with an upper bound it is not safe to write to the List. After all, a Car is always a Vehicle, but a Vehicle is not always a Car.
By using wildcard, Well, we got:
1) A way to specify that a collection can contain any type.
2) A way to specify that a collection can contain any subtype of X.
3) ... and this at the price of not being able to write to such a collection.
2 comments:
Try to use a syntaxhighlighter please, much easier to read the code examples.
thanks for the suggestion,,,, i will work on that
Post a Comment