Why can't I do this in Java:
public class TestClass {
public <T extends TestClass> T test(){
return this; // error here
}
}
As I understand, this
will always be an instance of some class that extends TestClass
, so why the code above is not allowed by compiler? Even if I will extend the TestClass
then type of this
will fit extends TestClass
anyway. I get the following error:
Error:(4, 16) java: incompatible types: TestClass cannot be converted to T
Say you have SubTestClass extends TestClass
, and you write:
TestClass instance = new TestClass();
SubTestClass result = instance.test();
This is legal regarding the signature of your test()
class, although nonsense (1). The compiler will deduce that T
is the class SubTestClass
. And then it's clear that a TestClass
instance isn't instanceof SubTestClass
. So with legal usage of your test()
method, returning this
can produce type mismatches, and that's what the compiler tells you.
With your test()
signature, it's impossible to return anything other than null
, because null
is the only value you can assign to a variable of unknown type.
Let me explain that last claim (asked for in comments): The implementation of the test()
method has to return some value that matches the T
type, and the concrete type (deduced from the call situation to be SubTestClass
) isn't deducible to the method - there's nothing in the arguments or in the instance fields where it can read out the requirement to return a SubTestClass
in this situation. In another call situation, it might be required to return AnotherSubTestClass
, and there's no way it can tell the first from the second situation.
If you return this
(with (T)
casting to make it pass the compiler), it will fail either in the first or in the second or in both situations. So you can't do that without high risk of failure.
The only value that you can successfully assign to both a SubTestClass
and a AnotherSubTestClass
variables, is the null
value. So that's the only value you can safely return from a method with such a signature.
(1) Having a generic method where the generic type can't be deduced from the parameters, but instead only from the expected result type, can hardly work - how should the method know what the caller expects?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With