I cannot really understand this Incompatible types
compilation error.
interface Request {}
interface Response {}
class Foo {
<RQ extends Request, RS extends Response> RS foo(RQ rq) {
// This doesn't compile: Incompatible types error
return foo3(foo2(rq));
/* This compiles fine */
// RS rs = foo2(rq);
// return foo3(rs);
}
<RS extends Response, RQ extends Request> RS foo2(RQ rq) {
return null;
}
<RS extends Response> RS foo3(RS rs) {
return rs;
}
The curious thing for me is that the code compiles fine if in the method foo
I replace this:
return foo3(foo2(rq));
by:
RS rs = foo2(rq);
return foo3(rs);
For sure I'm missing something, but I still don't get why.
Thanks for the help.
That's because in the case of using
RS rs = foo2(rq);
return foo3(rs);
the compiler know which concrete type (RS
) to use for the specialization of foo2
. You are telling it specifically which type you want.
In the case of foo3(foo2(rq));
the compiler cannot deduce that. So you just get the less specialized type Response
as result of foo2
, which doesn't work with foo3
.
Note that this automatic deduction is necessary because the type parameters RS
are independent for every method. Nobody guarantees that they refer to the same type in the whole class. If you want them to be the same in the whole class, make the class itself generic, not the methods.