Looking at the following code, why doesn't the second invocation of dump get compiled? And how can I fix it without removing the wildcard?
import java.util.ArrayList;
import java.util.List;
class Column<A, T extends Object> {
}
public class Generics {
static void main(String[] args) {
Integer i = 5;
// this works
List<Column<Integer, ?>> columns1 = new ArrayList<Column<Integer, ?>>();
dump(columns1, i);
// this doesn't
List<Column<Integer, String>> columns2 = new ArrayList<Column<Integer, String>>();
dump(columns2, i);
}
static <A, T> void dump(Iterable<Column<A, ?>> columns, A value) {
for (Column<A,?> col: columns) {
System.out.println(col);
}
}
}
The JDK's compiler gives
Generics.java:18: <A,T>dump(java.lang.Iterable<Column<A,?>>,A) in Generics cannot be applied to (java.util.List<Column<java.lang.Integer,java.lang.String>>,java.lang.Integer)
dump(columns2, i);
^
1 error
Guidelines for Wildcards. Upper bound wildcard − If a variable is of in category, use extends keyword with wildcard. Lower bound wildcard − If a variable is of out category, use super keyword with wildcard. Unbounded wildcard − If a variable can be accessed using Object class method then use an unbound wildcard.
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types. Cannot Create, Catch, or Throw Objects of Parameterized Types. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.
The polymorphism applies only to the 'base' type (type of the collection class) and NOT to the generics type.
Since columns
in dump()
acts as a producer of objects, you need to declare it with extends
(the general rule is "producer - extends
, consumer - super
"):
static <A, T> void dump(Iterable<? extends Column<A, ?>> columns, A value) {
for (Column<A,?> col: columns) {
System.out.println(col);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With