Java类的实例化顺序
- 1.父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
- 2.子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
- 3.父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
- 4.父类构造方法
- 5.子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
- 6.子类构造方法
注意 :
类中的实例成员,等价于实例代码块(构造代码块)。也就是说实例代码块执行的时候,也会执行实例成员的代码。
类中的静态成员,等价于静态代码块。也就是说静态代码块执行的时候,也会执行静态成员的代码。
具体请看下面例子 :
/**
* Parent
*/
class Parent {
/** 静态成员 */
static int staticNum = 100;
/** 实例成员 */
int num = 10;
/** 静态代码块 */
static { System.out.println("父类静态代码块"); }
/** 代码块 */
{ System.out.println("父类代码块"); }
/** 构造器 */
public Parent(){
System.out.println("父类构造器");
}
}
/**
* Children
*/
class Children extends Parent {
/** 静态成员 */
static int staticNum = 100;
/** 实例成员 */
int num = 10;
/** 静态代码块 */
static { System.out.println("子类静态代码块"); }
/** 代码块 */
{ System.out.println("子类代码块"); }
/** 构造器 */
public Children(){
System.out.println("子类构造器");
}
}
/**
* JavaTest
*/
public class JavaTest {
public static void main(String[] args) {
new Children();
}
}
输出:
父类静态代码块
子类静态代码块
父类代码块
父类构造器
子类代码块
子类构造器
经典面试题:
/**
* JavaTest
*/
class JavaTest {
public static void main(String[] args) {
f();
}
static JavaTest t = new JavaTest();
static { System.out.println("静态代码块"); }
{ System.out.println("代码块"); }
public JavaTest(){
System.out.println("构造器");
System.out.println("num = " + num + ", staticNum = " + staticNum);
}
public static void f() {
System.out.println("静态方法");
}
int num = 100;
static int staticNum = 200;
}
输出:
代码块
构造器
num = 100, staticNum = 0
静态代码块
静态方法
解析:
1.当调用f()方法时,首先依次从上到下加载JavaTest类的静态代码块。即首先执行**static JavaTest t = new JavaTest()
静态成员**。
2.该静态成员待用构造方法,而调用构造方法时会先执行代码块,再执行构造方法。因此首先调用代码块
{ System.out.println("代码块"); }
int num = 100;
再调用构造方法内容,即
System.out.println("构造器");
System.out.println("num = " + num + ", staticNum = " + staticNum);
而此时,num已经赋值,而staticNum尚未赋值,所以 打印内容为num = 100, staticNum = 0
此时**static JavaTest t = new JavaTest()
静态成员** 执行完毕,再执行下面的静态代码块,依次是
static { System.out.println("静态代码块"); }
static int staticNum = 200;
最后再执行f()方法
System.out.println("静态方法");