Ⅰ:
本题答案:C
初始化过程:
- 初始化父类中的静态成员变量和静态代码块 ;
- 初始化子类中的静态成员变量和静态代码块 ;
- 初始化父类的普通成员变量和代码块,再执行父类的构造方法;
- 初始化子类的普通成员变量和代码块,再执行子类的构造方法;
(1)初始化父类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y
(2)再执行父类的构造方法;输出X
(3) 初始化子类的普通成员变量和代码块,执行 Y y=new Y(); 输出Y
(4)再执行子类的构造方法;输出Z
所以输出YXYZ
Java中的初始化
1 方法的局部变量:必须手动初始化,否则编译器会报错
2 类的数据成员(字段):基本数据类型和引用数据类型都会有一个默认值。
3.构造器初始化的顺序:
(1)在类的内部,变量定义的先后顺序决定了初始化的顺序,但是都会在方法(包括构造器)之前执行。
(2)静态数据的初始化(static关键字不能应用于局部变量,只能作用于域):初始化的顺序为先静态对象(如果该静态对象已经被初始化过,就不会再进行初始化,静态对象只初始化一次),再“非静态对象”。
注意:
- 类中有静态代码块时,当首次生成这个类的对象,或者首次访问这个类的静态数据成员时,这个静态代码块就会执行。
- 在类进行初始化时,一般都是先成员变量,后成员方法(包括构造方法),而在变量和方法中,被static关键字修饰的要优先执行。
来源:牛客网
Ⅱ:
解析:
首先,super()函数指的是调用父类的构造方法
① new B()执行B的无参构造函数(父类A中没有无参构造函数),第一行是super(5); 此时super(5)执行的是A的构造函数,A的构造函数调用的是setValue()方法,由于B重写了A的这个方法(动态绑定),所以,执行的是B的 setValue()方法, 即传入的参数是2*5=10
。
因为B的setValue方法中有super
,所以调用的是父类的 setValue()方法,即value=10,第一行执行完毕。
第二行是 setValue(getValue()-3)
; B没有getValue()方法,故执行父类的getValue()方法,先执行value++
,value=10+1=11
,先保存在临时栈中。
再执行finally方法,finally中的this指向B的对象,故调用B的 setValue()方法(动态绑定)。 value=2*11=22
,22为第一个打印到屏幕上的数字。
接下来参数 getValue()-3=11-3=8
,传入B的 setValue()方法,value=2*8=16
至此,new B()执行结束。
② new B(). getValue()
B没有 getValue(),故执行A的 getValue(),16+1=17
,保存到临时栈中,
finally调用B的 setValue()方法,value=17*2=34
,为第二个打印到屏幕上面的数字,最后主函数打印返回值,也就是打印try保存到临时栈中的17
。
注意:
此处A中的getValue方法中的try中有return语句,所以需要优先执行finally中的语句,说是如此,其实在try中除了return语句,其余的语句都是先于finally语句的,只不过都是先保存在临时栈中。故如果try中带有return时,会优先执行完除return之外的语句,然后才是执行finally语句。