收获:对于java类初始化和实例初始化的思考。
public class Father{
private int i = test();
private static int j = method();
static{
System.out.print("(1)");
}
Father(){
System.out.print("(2)");
}
{
System.out.print("(3)");
}
public int test(){
System.out.print("(4)");
return 1;
}
public static int method(){
System.out.print("(5)");
return 1;
}
}
public class Son extends Father{
private int i = test();
private static int j = method();
static{
System.out.print("(6)");
}
Son(){
System.out.print("(7)");
}
{
System.out.print("(8)");
}
public int test(){
System.out.print("(9)");
return 1;
}
public static int method(){
System.out.print("(10)");
return 1;
}
public static void main(String[] args) {
Son s1 = new Son();
System.out.println();
Son s2 = new Son();
}
}
运行结果:
类初始化和实例初始化
java程序初始化时,最先进行的是类初始化,然后再进行实例初始化。这也比较容易理解,先有类才有对象。
其次是先进行静态代码的初始化,再非静态代码的初始化,最后进行构造器代码的执行。
1. 类初始化
(1)一个类要创建实例需要先加载并初始化该类。其中,main方法所在的类需要先加载和初始化。
(2)一个子类要初始化需要先初始化父类
(3)java的类初始化,其实是执行了一个()方法。====
- ()方法由静态类变量显式赋值代码和静态代码块组成;
- 静态类变量显示赋值代码和静态代码块代码从上到下顺序执行。即静态的代码按顺序执行;
- ()方法只执行一次。
2. 实例初始化过程
实例初始化其实是执行了()方法。
- ()方法可能重载有多个,有几个构造器就有几个()方法;
- ()由非静态实例变量显式赋值代码和非静态代码块、对应构造器代码组成;
- 非静态实例变量显式赋值代码和非静态代码块,这些非静态代码,按照顺序由上到下执行,而对应的构造器代码最后执行;
- 每次创建实例对象,调用对应构造器,执行的就是对应的()方法;
- ()方法的首行是super()或super(实参列表),即对应父类的方法。不论写不写super(),它都是存在的。
3. 方法的重写Override
(1)哪些方法不能被重写
- final 方法
- 静态方法
- private等子类中不可见的方法
(2)对象的多态性
- 子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码。
- 非静态方法默认的调用对象是 this
- this 对象在构造器或者说()方法中,就是正在创建的对象
4. 进阶
(1)Override 和 Overload 的区别?
(2)Override 重写的要求?
(3)了解《JVM虚拟机规范》中关于和方法的说明、invokespecial指令
5. 例题解析
-
main方法所在类是Son,所以先加载Son所在类;
-
由于子类初始化之前需要先初始化父类,所以先加载 Father, 而 Father 没有父类了,所以直接加载Father;
-
类加载过程,即执行()方法,执行静态的代码,并且这些静态的代码是按照从上到下执行的。因此,执行了(5)然后是(1);
-
父类加载完成后,开始加载子类。同样地,按顺序执行了(10)(6);
-
类加载完毕后,开始执行实例加载过程。同样地,实例化子类之前要先实例化父类。
-
实例化对象的过程,实质上是执行了()方法,于是按顺序执行非静态的代码。这里先执行的是
private int i = test();
实际上,非静态方法默认的调用对象是 this, 因此这句代码等同于:
private int i = this.test();
而 this 对象在构造器,或者说()方法中,就是正在创建的对象,也就是正在创建的Son对象,也就是调用了子类重写的test()方法。所以输出的应该是(9)。
-
执行完了test()方法,接着就是执行非静态代码块,输出了(3),最后执行构造方法里的代码,输出了(2)。
-
按同样的规则,输出了(9)(8)(7)。