Q: Вопрос по порядку вызова конструктора базового класса class B {
    private B() {
        System.out.println("No args constructor B");
    }
    protected B(String str) {
        System.out.println("Constructor with string B");
    }
}

class A extends B {
    public A() {
        this("some string");
        System.out.println("No args constructor A");
    }
    public A(String str) {
        super(str);
        System.out.println("Constructor with string A");
    }
}

public class Main {
    public static void main(String[] args) {
        B b = new A();
    }
}

На просторах интернета не нашел точного ответа на вопрос. Прошу подсказать, верно ли я понимаю порядок вызова конструктора базового класса:
Если в конструкторе потомке (Конструктор1) первой строкой вызвать другой конструктор потомка (Конструктор2), то вызов конструктора базового класса из Конструктора1 произведен не будет, вместо этого управление будет передано сразу в конструктор 2 и уже там, если нет вызова другого конструктора потомка, будет вызван конструктор базового класса.
Я правильно понимаю логику инициализации?

A: при инициализации объекта, компилятор вызовет сначала дефолтный конструктор(который без аргументов), он неявно создаётся во всех классах, если его не переопределить.
если у класса есть "родитель", то по средствам ключевого слова super() будет вызываться конструктор "родителя" потом его "родителя" и тд до самого верха, пока не вызовется конструктор класса Object от которого в java наследуются все классы.
если написать следующее
public class Main extends Object{
} 

ide напишет Class 'Main' explicitly extends 'java.lang.Object'
типо зачем ты мне это пишешь, я и так знаю что всё наследуется от Object
если написать так
class Class1{
    public Class1() {
        System.out.println("class1");
    }
}
class Class2 extends Class1{
    public Class2() {
        System.out.println("class2");
    }
}
class Class3 extends Class2{
    public Class3() {
        System.out.println("class3");
    }
}

public class Main {

    public static void main(String[] args) {

       Class3 class3 = new Class3();
    }
}  

то вывод будет следующий
class1
class2
class3  

получается своего рода лесенка, перед тем как создать обьект, сначала вызовется конструктор родительского класса, потом его родителя и тд, пока не дойдёт до главного папы(Object), а далее будут вызывается конструкторы по "лесенке" вниз.

A: Если бы вы запустили код в своём вопросе, вы бы увидели следующий вывод:
Constructor with string B
Constructor with string A
No args constructor A

То есть ваше понимание логики инициализации вполне корректно:

*

*При вызове конструктора без параметров new A() происходит вызов перегруженного конструктора A(String str)

*При вызове перегруженного конструктора A(String str) происходит вызов аналогичного конструктора базового класса protected B(String str).  Вызов дефолтного конструктора базового класса в данном случае невозможен (например, при помощи super();), так как он определён как приватный!

*Завершается перегруженный конструктор базового класса, код возвращается в перегруженный конструктор потомка.

*Завершается перегруженный конструктор потомка, код возвращается в конструктор без параметров потомка.

