Как правило, не очень хорошо вызывать методы класса до его создания; тем не менее, Java допускает исключения в том случае, если вы знаете, что делаете (т. е. у вас нет доступа к неинициализированным полям). С помощью абстрактного метода я не думаю, что можно «знать», что вы делаете в родительском классе.
Приведенный выше код может быть легко решен путем наложения более строгой интерпретации «класс выполняет свои обязанности». Инициализация подкласса не является обязанностью суперкласса, поэтому не должно быть прерогативой суперкласса вызывать код подкласса, прежде чем такая инициализация может быть завершена.
Да, это делается в JDK (подобно коду HashMap) с помощью специальных методов init (), которые подразумевают инициализацию всего кода подкласса; но я бы сказал, что следующий шаблон вызовов намного чище и обеспечивает большую гибкость.
public class SSCCE {
static abstract class A {
public A() {
}
abstract void method();
}
static class B extends A {
final String[] arr = new String[] { "foo", "bar" };
public B() {
super();
method();
System.out.println("In B(): " + Arrays.toString(arr));
}
void method() {
System.out.println("In method(): " + Arrays.toString(arr));
}
}
public static void main(String[] args) {
new B().method();
}
}
это кажется намного чище во многих отношениях. В противном случае всегда есть возможность создать ваши объекты с надлежащей «последовательностью инициализации» через фабрику.