Some example code:
public class Main {
class SomeType {
}
class A {
protected <T extends SomeType> T createSomething()
{
return null; // Don't worry about this.
}
}
class B extends A {
@Override
protected <T extends SomeType> T createSomething()
{
SomeType orig = super.createSomething();
// do some stuff with orig
return orig;
}
}
}
What am I getting wrong here?
On the line
return orig;
the compiler spits out the error that
Type mismatch: cannot convert from Main.SomeType to T
Thanks to <T extends SomeType>, we can be sure that T is always a subtype of SomeType, right? So why can't I just return the supertype SomeType?
I've already read <? extends SuperType> cannot be applied to SuperType and Explanation of the get-put principle but I don't see how it applies here.

Thanks to
<T extends SomeType>, we can be sure thatTis always a subtype ofSomeType, right?
Right.
So why can't I just return the supertype
SomeType?
Because it might not be a T!
Put it this way - imagine SomeType is Object, and T is String. You're suggesting that this code should work:
String foo() {
return new Object();
}
It works the other way round - you can return a subtype reference for a method declared to return a supertype, but that's different.
The fix is easy though - just change orig to be of type T:
T orig = super.createSomething();
Then it compiles with no problems.
See more on this question at Stackoverflow