6

I'm facing an issue with generic types:

public static class Field<T> {

    private Class<? extends T> clazz;

    public Field(Class<? extends T> clazz) {
        this.clazz = clazz;
    }

}

public static void main(String[] args) {

    // 1. (warning) Iterable is a raw type. References to generic type Iterable<T> should be parameterized.
    new Field<Iterable>(List.class);

    // 2. (error) The constructor Main.Field<Iterable<?>>(Class<List>) is undefined.
    new Field<Iterable<?>>(List.class);

    // 3. (error) *Simply unpossible*
    new Field<Iterable<?>>(List<?>.class);

    // 4. (warning) Type safety: Unchecked cast from Class<List> to Class<? extends Iterable<?>>.
    new Field<Iterable<?>>((Class<? extends Iterable<?>>) List.class);

}

What's the best solution between the 1. and the 4. (or any other one by the way)?

sp00m
  • 47,968
  • 31
  • 142
  • 252
  • 3
    What do you want to achieve? It's hard to answer your question without knowing that... – Anders R. Bystrup Feb 06 '13 at 10:07
  • Class can be a nasty beast. 5th option: `new Field>(List.class)` ('warning: unchecked assignment'). – akaIDIOT Feb 06 '13 at 10:11
  • possible duplicate of [Class object of generic class (java)](http://stackoverflow.com/questions/1079279/class-object-of-generic-class-java) – artbristol Feb 06 '13 at 10:18
  • @AndersR.Bystrup It's an example that reflects an issue I'm facing with the custom objects of the project I'm working on. So I'm afraid I can't be more specific, sorry... – sp00m Feb 06 '13 at 10:33
  • @akaIDIOT With your solution, I'm not getting a warning but an error: *The constructor Main.Field>(Class) is undefined*. – sp00m Feb 06 '13 at 10:34
  • @sp00m curious, copied the warning from my IDE running Java 1.7... – akaIDIOT Feb 06 '13 at 10:34
  • @akaIDIOT I'm using 1.6, maybe 1.7 is more compliant with those generic types? – sp00m Feb 06 '13 at 10:41
  • @sp00m could be, don't have Java 1.6 handy; can't check... – akaIDIOT Feb 06 '13 at 10:43

1 Answers1

5
public class Field <T> {
    private Class <? extends T> clazz;

    public <TT extends T> Field (Class <TT> clazz) {
        this.clazz = clazz;
    }

    public static void main (String [] args) {
        new Field <Iterable <?>> (List.class);
    }
}
Mikhail Vladimirov
  • 13,572
  • 1
  • 38
  • 40
  • I haven't seen type parameters on a constructor before, but nice solution – SpaceTrucker Feb 06 '13 at 10:24
  • This is really awesome, I had never noticed that you could infer generic types to constructors. That said, I don't really understand why this solution doesn't cause the same error as in 2... – sp00m Feb 06 '13 at 10:39
  • @sp00m Pretty sure it abuses a compiler bug ( see http://stackoverflow.com/q/11570215/774444 ). – Ben Schulz Feb 06 '13 at 13:23