Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wildcard in Generics doesn't work

Tags:

java

generics

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
like image 786
Axel Avatar asked Sep 26 '11 15:09

Axel


People also ask

How do you use generic wildcards?

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.

What is wild card in generics?

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).

What are not allowed for generics?

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.

Can I use polymorphism in generics?

The polymorphism applies only to the 'base' type (type of the collection class) and NOT to the generics type.


Video Answer


1 Answers

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);
    }
}
like image 58
axtavt Avatar answered Sep 23 '22 16:09

axtavt