I have an abstract class with one abstract method:
class A {
public abstract Element getA();
}
I have several classes that have already implemented this abstract class, and they work fine. For some reasons, I cannot change the method signature of these classes.
class A1 extends A {
@Override
public Element getA() {
// Implementation in A1
}
}
Now, I'm creating a new class, A2, which extends the abstract class A. However, instead of returning an Element object, I want it to return a list of Element objects.
class A2 extends A {
@Override
public List<Element> getA() {
// Implementation in A2
}
}
To change the return type of the subclass, I thought about using covariant return types. So, I changed the return type of the abstract class to Object:
class A {
public abstract Object getA();
}
It compiles without errors and I have no errors when calling A2.getA() but I encounter a runtime error when calling A1.getA(): ""Missing implementation of resolved method 'abstract java.lang.Object getA()' of abstract class A.""
Any advice on how to resolve this issue? Thank you.
I think you might have forgotten to recompile
A1, after you changedA.There is no return type covariance in the JVM. The JVM doesn't consider
Element getA()to implementObject getA(). The Java compiler achieves return type covariance by generating an additional bridge method, with the correct return type.So after you changed
A.getA()to returnObject,A2is compiled to something like this:As far as the JVM is concerned, the
Object-returninggetAis what implements the abstract method. If you only have theList<Element>-returninggetA, the JVM thinks that the abstract method is unimplemented.Let's see what happens if you forgot to recompile
A1. The bytecode forA1would only contain anElement-returninggetA, because when you first compiledA1, the return type matched the abstract method's return type - there was no need to generate a bridge method. But now you changed the abstract method's return type, so the existinggetAmethod inA1doesn't implement the abstract method anymore!You should recompile
A1so that a bridge method is generated.