Это одна из ситуаций, когда синтаксис Java скрывает то, что происходит на самом деле, а C # делает его немного понятнее.
В C # ваш B будет выглядеть как
class B : A {
public B() : base(method()) {
}
private static String method() {
return "method invoker";
}
}
Хотя синтаксис Java помещает super(method)
в конструктор, он там на самом деле не вызывается: вся родительская инициализация запускается до вашего конструктора подкласса. Код C # показывает это немного яснее; помещая super(method())
в первую строку конструктора java, вы просто указываете java использовать параметризованный конструктор суперкласса, а не версию без параметров; таким образом, вы можете передать переменные родительскому конструктору, и они будут использованы при инициализации полей родительского уровня до запуска кода конструктора вашего ребенка.
Причина того, что super(method())
является действительной (как первая строка в конструкторе Java), заключается в том, что method()
загружается со статическими элементами - перед нестатическими, включая конструкторы - что позволяет быть вызванным не только до B()
, но и до A(String)
. Говоря
public B() {
String s = method();
super(s);
}
вы говорите компилятору java инициализировать суперобъект с помощью конструктора по умолчанию (потому что вызов super()
не первая строка), и вы готовы инициализировать подкласс, но компилятор затем запутывается когда он видит, что вы пытаетесь инициализировать с помощью super(String)
после того, как super()
уже запущен.