Reputation: 14438
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?
Upvotes: 3
Views: 211
Reputation: 62864
The magic words here are raws and multiple inheritance.
Lets first take a look on your returnC
method:
static <T extends ClsA> T returnC() {
return null;
}
The type T
is bounded with ClsA
, which means that if you invoke the raw returnC
method, then the return type will be simply ClsA
.
True, when you have this statement: ClsA ac = returnC();
the compiler succeeds with the compilation, because the raw return type of the method is ClsA
, which is compatible with the type of ac
.
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 returnI
method:
static <T extends IntA> T returnI() { // Here T extends the interface
return null;
}
Here, the type parameter is bound to IntA
only.
This, however, doesn't mean that the replacement type for T
must implement only IntA
- the type can implement IntA
and IntB
at the same time. Statements like IntB bi = returnI();
are allowed, because a type can implement multiple interfaces, but cannot implement multiple classes.
Consider this class:
class SomethingReallyCool implements IntA, IntB { }
This type is a valid substitute for the type-parameter of returnI()
and the proof for that is this statement:
IntB bi = YourClass.<SomethingReallyCool>returnI();
Why? Because it's a class that implements IntA
and this is the only thing the compiler cares about.
Upvotes: 1