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 can be 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?
It is because the compiler is designed in the way that react (E e) cannot accept any parameter type except null.
Try compound.react(null). It only takes null without compilation error.
The compiler is designed with this rule that you cannot pass a wildcard type object (eg <? extend Organic> ) as any parameter of generic type ( eg E e).
The compiler won't know what exactly you will pass to react. It can be Organic, Aliphatic or Hexane. Can you do this Hexane h = new Aliphatic()? No, it won't compile.
Suppose you have this code:
All I want to emphasize is that the compiler is designed in this way to prevent programmers from assigning an object to a wrong type.
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 type T because the compiler can't 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 this should be safe
but 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 right hand side. If the compiler allowed this then it would also have to allow
which 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 say Organic<? extends Organic<?>> or similar rather than just Organic<? extends Organic>)
The WildCardCollection class is not a generic type.
But you can define a generic method inside any class of any type on-the-fly.
Your WildCardCollection is not bounded to any generica type, only myMethod does.
The myMethod says it can accept any Items type. T is only limited to this myMethod locally. The compiler does not care what type of parameter is passed to myMethod as long as that parameter is Item type.
Suppose you have this code:
The compiler prevents you from passing any Item or SubItem to myMethod because it doesn't know what T is actually bounded to during compile-time.
Inside the myMethod, can you do this?
No. Because the compiler bounds the WildCardCollection's T to myMethod's T. But the compiler won't know what exactly T is during compile-time. So, the compiler is designed in the way to prevent you from passing any generic T parameter to any method.