I ran into this today and the only thing I can think is that this is a bug in the Java compiler. The following code compiles, but certainly seems incorrect (since testMethod has a differenet signature in the child but overrides the parent) and will throw class cast exceptions at runtime.
public interface TestInterface<T> {
public List<String> testMethod(); // <-- List<String>
}
public class TestClass implements TestInterface {
@Override
public List<Integer> testMethod() { // <-- List<Integer> overriding List<String>!!
return Collections.singletonList(1);
}
}
And using the above structure:
public void test() {
TestInterface<Boolean> test = new TestClass();
List<String> strings = test.testMethod();
for (String s : strings) {
System.out.println(s);
}
}
All of this compiles fine, but will obviously throw class cast exceptions if you run it.
If you remove <T>
from TestInterface
, or fill T
in in the line TestClass implements TestInterface<T>
then the code will no longer compile, which makes sense. Imo <T>
should have no bearing on the compilation of testMethod
since it plays no part in that method.
Maybe adding <T>
to TestInterface is causing the compiler to type-erase the method signatures even though T
doesn't participate in those methods...?
Does anyone know what is going on here?
If you instantiate a generic class as a raw type, all generic type parameters contained in it are going to be omitted by the compiler, hence it gives you no warnings/errors during compilation. I.e. declaring
public class TestClass implements TestInterface ...
effectively degrades the code into
public interface TestInterface {
public List testMethod();
}
public class TestClass implements TestInterface {
@Override
public List testMethod() {
return Collections.singletonList(1);
}
}
which indeed compiles fine.
A similar problem was posted a couple of weeks ago, the answer to which stating that it is not a compiler bug, rather a deliberate design decision for backward compatibility.
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