Рассмотрим следующее, например.
public class H{
int a;
public H(){
a=5;
}
public H(String x){
this();
}
{a=0;}
public static void main(String []a){
System.out.print(new H("").a);
}
}
O/P равно 5, что означает, что блок инициализации выполняется первым перед этим(), но в соответствии с тем, почему this() и super() должны быть первым оператором в конструкторе? первым утверждением должно быть это(). Как это случилось..???
Если вы знаете о конструктор-цепочке
Первый новый H ("") вызывает ваш конструктор parameterized- там, где он находит this()
поэтому вызов переходит к непараметрированному конструктору, там инициализатор выполняется первым, а a инициализируется до нуля, а затем ваш a =5
устанавливает a в 5 и наконец печатает 5
JLS очень специфичен в этом (акцент мой):
Перед возвратом ссылки на вновь созданный объект в результате указанный конструктор обрабатывается для инициализации нового объекта, используя следующую процедуру:
Назначьте аргументы для конструктора новым созданным переменным параметра для этого вызова конструктора.
Если этот конструктор начинается с явного вызова конструктора (§8.8.7.1) другого конструктора в том же классе (с помощью
this
), то затем оценивайте аргументы и обрабатывайте вызов конструктора рекурсивно, используя эти пять шагов. Если вызов конструктора завершается внезапно, то эта процедура завершается внезапно по той же причине; в противном случае перейдите к шагу 5.Этот конструктор не начинается с явного вызова конструктора другого конструктора в том же классе (используя это). Если этот конструктор относится к классу, отличному от Object, то этот конструктор начнет с явного или неявного вызова конструктора суперкласса (используя super). Оцените аргументы и обработайте вызов конструктора суперкласса рекурсивно, используя эти пять шагов. Если вызов конструктора завершается внезапно, то эта процедура завершается внезапно по той же причине. В противном случае перейдите к шагу 4.
Выполните инициализаторы экземпляра и инициализаторы переменных экземпляра для этого класса, присваивая значения инициализаторов переменных экземпляра соответствующим переменным экземпляра в порядке слева направо, в котором они отображаются в текстовом виде в исходном коде для класса. Если выполнение любого из этих инициализаторов приводит к исключению, то никакие новые инициализаторы не обрабатываются, и эта процедура завершается внезапно с тем же исключением. В противном случае перейдите к шагу 5.
Выполните оставшуюся часть тела этого конструктора. Если это выполнение завершается внезапно, то эта процедура завершается внезапно по той же причине. В противном случае эта процедура завершится нормально.
Полужирный текст в разделе 2 означает, что когда он выполнит this
, он снова вызовет эти пять шагов при вызове такого конструктора. Поскольку вы вызываете this()
без аргументов, он будет следовать этим шагам, но шаг 2 не будет выполнен, так как нет вызова this()
, вместо этого он выполнит шаги 3 и 4, а на шаге 4 он выполнит экземпляр инициализаторы и инициализаторы переменных экземпляра для класса. Затем элемент управления вернется к выполнению конструктора без параметров, который выполняет a = 5
.