class C {
C() { //(5)
System.out.print("C"); //(6)
} //(7)
}
class A {
C c = new C(); //(4)c:null (8)
A() {
this("A");
System.out.print("A");
}
A(String s) { //(3)
System.out.print(s); //(9)
} //(10) s:B
}
public class Test extends A{
Test() {
super("B"); //(2)
System.out.print("B"); //(11)
}
public static void main(String[] args) {
new Test(); //(1)
}
}
A.BB B.CBB C.BAB D.None of the above
正确答案: B
初始化顺序:
当实例化对象时,对象所在类的所有成员变量首先要进行初始化,当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象。Java程序的初始化一般遵循3个原则:(1)静态对象优先于非静态对象,其中静态对象只初始化1次(2)父类优先于子类(3)按照成员变量的定义顺序
所以,执行顺序如下:
1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化;
3.其次,初始化父类的普通成员变量和代码块,再执行父类的构造方法;
4.最后,初始化子类的普通成员变量和代码块,再执行子类的构造方法;
(1)初始化父类的普通成员变量和代码块,执行 C c = new C();输出C
(2)super("B");表示调用父类的有参构造函数,输出B
(3) System.out.print("B");
所以输出CBB
静态代码块:在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。
//如果类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。
//注意:1 静态代码块不能存在于任何方法体内。2 静态代码块不能直接访问静态实例变量和实例方法,需要通过类的实例对象来访问。
class Code{
{
System.out.println("Code的构造块");
}
static{
System.out.println("Code的静态代码块");
}
public Code(){
System.out.println("Code的构造方法");
}
}
public class CodeBlock03{
{
System.out.println("CodeBlock03的构造块");
}
static{
System.out.println("CodeBlock03的静态代码块");
}
public CodeBlock03(){
System.out.println("CodeBlock03的构造方法");
}
public static void main(String[] args){
System.out.println("CodeBlock03的主方法");
new Code();
new Code();
new CodeBlock03();
new CodeBlock03();
}
}
执行结果:
CodeBlock03的静态代码块
CodeBlock03的主方法
Code的静态代码块
Code的构造块
Code的构造方法
Code的构造块
Code的构造方法
CodeBlock03的构造块
CodeBlock03的构造方法
CodeBlock03的构造块
CodeBlock03的构造方法
构造代码块:直接在类中定义且没有加static关键字的代码块称为构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。
public class CodeBlock02{
{
System.out.println("第一代码块");
}
public CodeBlock02(){
System.out.println("构造方法");
}
{
System.out.println("第二构造块");
}
public static void main(String[] args){
new CodeBlock02();
new CodeBlock02();
}
}
执行结果:
第一代码块
第二构造块
构造方法
第一代码块
第二构造块
构造方法