1、类加载题,求执行结果
package Test2;
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(){ super();//写或不写都在,在子类的构造器中一定会调用父类的构造器 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) {
} }
|
- Main方法所在的类需要 先加载和初始化
- 但是,一个子类要初始化,需要先初始化父类
- 一个类初始化就是执行<clinit>()方法,这个方法不是我们编写的,是编译器生成的,在字节码文件中可以看到
- <clinit>()方法由静态类变量显示赋值代码和静态代码块组成
- 类变量显示赋值代码和静态代码块代码从上到下顺序执行
- <clinit>()方法只执行一次
因此,这题先初始化父类,:(5)(1)
然后,再初始化子类:(10)(6)
因为是print,所以输出结果为(5)(1)(10)(6)
2、类的实例化运算结果以及分析过程
package Test2;
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)"); }
private int test() { System.out.print("(4)"); return 1; } private 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(){ super();//写或不写都在,在子类的构造器中一定会调用父类的构造器 System.out.print("(7)"); } { System.out.print("(8)"); }
public static test(){ System.out.print("(9)"); return 1; } public static int method(){ System.out.print("(10)"); return 1; } public static void main(String[] args) { Son son1 = new Son(); System.out.println(); Son son2 = new Son(); } }
|
【注意】父类中的i=test()执行的是子类中的重写的test()方法
执行结果:(5)(1)(10)(6)(4)(3)(2)(9)(8)(7)
(4)(3)(2)(9)(8)(7)
3、类的加载(即初始化)应注意的问题
- Main方法所在的类需要 先加载和初始化
- 但是,一个子类要初始化,需要先初始化父类
- 一个类初始化就是执行<clinit>()方法,这个方法不是我们编写的,是编译器生成的,在字节码文件中可以看到
- <clinit>()方法由静态类变量显示赋值代码和静态代码块组成
- 类变量显示赋值代码和静态代码块代码从上到下顺序执行
- <clinit>()方法只执行一次
4、类的实例化应注意的问题
父类非静态变量显示赋值代码à父类非静态代码块à父类构造器à
子类非静态变量显示赋值代码à子类非静态代码块à子类构造器