Well-known at runtime common extended template template

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 the reaction method with the argument Organic? Generic link type <? extends Organic> <? extends Organic> suggests that a generic instance type can be either organic or a subtype of Organic.

Is this because the compiler does not know this type of typing of the instance until the runtime type is set, does it bind any value to its general criteria?

Why does this case work? Is this the same case?

 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(); } } 
0
source share
1 answer

Quite simply, if you have an object of some general type with a parameter of type T created using a template ? extends X ? extends X , then you cannot call object methods that accept parameters of type T , because the compiler cannot guarantee type safety. However, you can call methods that return T (and assign the return value to a variable of type X ). In your specific example, it looks like it should be safe

 Organic<? extends Organic> compound = new Aliphatic<Organic>(); compound.react(new Organic()); 

but remember that the compiler must match the react call based on the declaration type ( ? extends Organic ), it cannot rely on what you assigned to RHS. If the compiler allowed this, then it would also have to be allowed

 Organic<? extends Organic> compound = new Aliphatic<Hexane<?>>(); compound.react(new Organic()); 

which is clearly wrong - this is exactly the same situation as

 Collection<? extends Number> nums = new ArrayList<Float>(); nums.add(Integer.valueOf(1)); 

(all this aside from the fact that, since Organic is common, you need to say Organic<? extends Organic<?>> or the like, and not just Organic<? extends Organic> )

+2
source

Source: https://habr.com/ru/post/1442920/


All Articles