Редактировать Действительно, Java не позволяет конструктору выполнять какие-либо вычисления перед вызовом конструктора класса родителя, даже если они включают только статические методы (как и ваши calculateX
) и результаты присваивается только переменным, которые являются частными для класса (например, ваши _a
, _b
и _c
) или локальными для конструктора.
Однако есть способ обойти это: вызвать другой конструктор с результатом вызова calculateX
, назначенного его параметру - тогда вы можете получить доступ к этому результату через другой конструктор.
public class MyClass extends ParentClass {
private int _a,_b,_c;
public MyClass(String input) {
this(calculateA(input));
}
private MyClass(int a) {
this(a, calculateB(a), calculateC(a));
}
private MyClass(int a, int b, int c) {
super(b + c);
this._a = a;
this._b = b;
this._c = c;
}
private static int calculateA(String text) {
try {Thread.sleep(1000);} catch (Exception e) {} // expensive ;-)
return text.length();
}
private static int calculateB(int a) { /* ... */ }
private static int calculateC(int a) { /* ... */ }
}
Редактировать 2 При большем количестве вычислений или промежуточных результатов, сохраняемых для последующего использования, этот подход приведет к еще более длинной цепочке конструкторов, состоящей только из this(...)
-коллсов. Более причудливое решение с использованием только двух конструкторов, публичного и частного, возможно с помощью вспомогательного класса (разумно внутреннего класса):
public MyClass(String input) {
this(new InitCalcResult(input));
}
private MyClass(InitCalcResult initCalcResult) {
super(initCalcResult.initB + initCalcResult.initC);
this._a = initCalcResult.initA;
this._b = initCalcResult.initB;
this._c = initCalcResult.initC;
}
private static class InitCalcResult {
private int initA, initB, initC;
InitCalcResult(String input) {
initA = calculateA(input);
initB = calculateB(initA);
initC = calculateC(initA);
}
}
(используя те же закрытые поля и статические методы calculateX
, что и выше).