class Aliphatic<F> extends Organic<F>{}
class Hexane<G> extends Aliphatic<G>{}
public class Organic<E>{
void react(E e){}
static void main(String[] args){
Organic<? extends Organic> compound = new Aliphatic<Organic>();
compound.react(new Organic());
}
}
Why can't I call react method with Organic argument?
The generic type ot the reference <? extends Organic>
says that the generic type of the instantiation canb either a Organic, or a subtype of Organic.
Is because the compiler doesn't know this instantiation generic type until runtime type an so, it does not bind any value to its generic criteria?
Why is this case working? Is this case the same?
public class WildcardCollection {
public static void main (String[] args){
WildcardCollection w = new WildcardCollection();
w.myMethod(new Items("hola",1)); //Compile
w.myMethod(new SubItems("nuevo",3)); //Compile
}
public <T extends Items> void myMethod(T a){ //Same as above
System.out.println("hi: "+a);
}
}
class SubItems extends Items {
SubItems(){};
SubItems(String s, int i){ super(s,i);}
}
class Items implements Comparable<Items> {
private String name;
private int value;
public Items() {}
public Items(String n, int i){ this.name = n; this.value = i;}
public String getName(){ return this.name;}
public int getValue(){ return this.value;}
public String toString(){ return "(" + this.name + "-" + this.value + ")";}
public int compareTo(Items i){
return this.value - i.getValue();
}
}
Quite simply, if you have an object of some generic type with a type parameter
T
instantiated with a? extends X
wildcard then you can't call methods on the object that take parameters of typeT
because the compiler can't guarantee type safety. However you can call methods that returnT
(and assign the return value to a variable of typeX
). In your specific example it looks like this should be safebut remember that the compiler has to match the
react
call based on the declaration type (? extends Organic
), it can't rely on what you've assigned on the RHS. If the compiler allowed this then it would also have to allowwhich is clearly not correct - it's exactly the same situation as
(all this is aside from the fact that since
Organic
is generic you need to sayOrganic<? extends Organic<?>>
or similar rather than justOrganic<? extends Organic>
)