I have a (for me) complex Java generics problem. I read through some documentation and understand some but certainly not all of what I should. Basically, for me, trying to solve it would result in try and error.
In the following, I give a condensed example of my code, once without any generics (so one can hopefully understand what I want to achieve) and the other with some additions that come closer to the solution. Please correct my second version and/or point me to specific documentation. (I have general documentation of Java generics. But my code seems to have several interfering challenges and it is hard to a correct solution)
About my example: There is an abstract base type and several implementing variants (only one is given). Method combine()
calls getOp1()
, which decides (depending on <some condition>
) if it should operate on its own instance or on a new one. After the calculation, it returns the target instance.
abstract class Base {
protected final Base getOp1() {
if(Util.isConditionMet()) { return getNewInstance(); }
else { return this; }
}
protected abstract Base getNewInstance(); // returns a new instance of an implementing class
public abstract Base combine(Base other);
}
class Variant extends Base {
public Variant getNewInstance() { return new Variant(); }
public combine(Variant op2) {
Variant op1 = getOp1();
op1.calculate(op2);
return op1;
}
private void calculate(Variant other) { /* some code */ }
}
The version with some generics added. This version is faulty and does not compile.
abstract class Base<T extends Base<T>> {
protected final T getOp1() {
if(Util.isConditionMet()) { return getNewInstance(); }
else { return this; }
}
protected abstract T getNewInstance(); // returns a new instance of an implementing class
public abstract T combine(T other);
}
class Variant<T extends Variant<T>> extends Base<T> {
protected T getNewInstance() { return new Variant(); }
public T combine(T op2) {
T op1 = getOp1();
op1.calculate(op2);
return op1;
}
private void calculate(T other) { /* some code */ }
}