Consider the following example,
class ClsA {}
class ClsB {}
interface IntA {}
interface IntB {}
And I have 2 very similar methods:
static <T extends ClsA> T returnC() { // Here T extends the class
return null;
}
static <T extends IntA> T returnI() { // Here T extends the interface
return null;
}
And then the method calls:
ClsA ac = returnC(); // This works fine based on inference.
IntA ai = returnI(); // Similarly this works fine based on inference.
But consider the below 2:
ClsB bc = returnC(); // ERROR as expected.
Eclipse Error:
Bound mismatch: The generic method returnC() of type Testing is not applicable for the arguments (). The inferred type ClsB&ClsA is not a valid substitute for the bounded parameter
<T extends ClsA>
But the following code compiles fine:
IntB bi = returnI(); // Works fine
Why is that for interface, the generics bound is not considered in return types?
The magic words here are raws and multiple inheritance.
Lets first take a look on your
returnCmethod:The type
Tis bounded withClsA, which means that if you invoke the rawreturnCmethod, then the return type will be simplyClsA.True, when you have this statement:
ClsA ac = returnC();the compiler succeeds with the compilation, because the raw return type of the method isClsA, which is compatible with the type ofac.The the raw return type is also the reason for which the statement
ClsB bc = returnC();does not compile.Now let's take a look on the
returnImethod:Here, the type parameter is bound to
IntAonly.This, however, doesn't mean that the replacement type for
Tmust implement onlyIntA- the type can implementIntAandIntBat the same time. Statements likeIntB bi = returnI();are allowed, because a type can implement multiple interfaces, but cannot implement multiple classes.Consider this class:
This type is a valid substitute for the type-parameter of
returnI()and the proof for that is this statement:Why? Because it's a class that implements
IntAand this is the only thing the compiler cares about.