you need to look at it differently. K cannot be anything when the method is called. In fact K will be resolved based upon the method call itself. Lets take a simple example
Here too M can be anything, but since we can't instantiate class Abc with anything except for Number or its sub-types, we know that M will actually resolve to Number or its sub-type.
Hmm you are right it doesn't work, I forgot that M/T can be resolved without relying on the parameters passed to the method. Like if there is a method like this
Now T can resolve depending upon the object passed to the method and also I can explicitly specify the type of T
So in this case even though I passed null to the method, I explicitly told the compiler during the method call that T is String. This is why the example I gave you doesn't work as T in that case can be explicitly set to a value which is out of bounds for class Gen1. I'm not going to lie to you, but I'm also confused why those 2 statements compile fine (maybe its due to sleep deprivation), its weird behavior...
Ankur, I am having a difficult time understanding Generics as well. I will give my best shot at explaining this:
1 should never compile anyway because ABS<? super Number> means ABS<Object> is valid, which is untrue. So even if K is Number or its subtype, this method is not applicable.
Similarly Line 3 will never compile because K can be anything and it has to be K extends Number. Hence it is not allowed.
But, one conflict between 1,2 & 3 is, what happens when you say
Now method on Line 1 for SubClassABS can be interpreted as
Line 2 can be
Line 3 can be
However your a in a.useMe(a)(Line 4) matches ABS<? super Number>(Line 1) as well as ABS<? extends Number>(Line 2) as well as ABS<Number>(Line 3)
So all 3 methods are applicable. The compiler will not know which one to choose at runtime. Now if you comment out 1 and 3, 2 will compile without any issue. 2 compiles because there is a chance that <K> defined in the method is Number.