如题所示,这是一个面试题,一般的java面试可能会被问到。
类的实例化,我们大概知道,静态的代码肯定是要先执行的,所以这里静态变量和静态代码块肯定先执行,那么谁先谁后怎么决定?谁先谁后就由代码书写的顺序来决定。
后面就是成员变量和构造函数执行顺序,假如构造函数先执行,那么问题来了,很多时候,我们会在构造函数中设置成员变量的值,比如下面的代码:
class Person{
private String name;
public Person(){}
public Person(String name){
this.name = name;//如果name没有被初始化,这里就给他赋值,肯定会有问题。
}
}
所以成员变量早于构造函数执行初始化。
这里还有一个父类和子类的关系,一般父类在前,子类在后。有了上面的关系,所以题目的答案如下:
1父类静态变量或者静态代码块->2子类静态变量或者静态代码块->3父类成员变量->4父类构造函数->5子类成员变量->6子类构造函数。
以上的顺序只在第一次类加载的时候会全部走完。因为静态成员和静态代码块是所有类实例共享的,不会每次都执行,后续如果再创建对象实例,只会进行实例变量和构造函数的执行过程。
package com.xxx.test;
class A {
@SuppressWarnings("unused")
private String hi = sayHi();
static {
System.out.print("1");
}
public A() {
System.out.print("2");
}
public String sayHi() {
System.out.print("3");
return "hello";
}
}
class B extends A {
static {
System.out.print("a");
}
public B() {
System.out.print("b");
}
}
public class Hello {
@SuppressWarnings("unused")
public static void main(String[] args) {
A a = new B();
A b = new B();
}
}
执行该代码,打印信息如下所示:1a32b32b
结果解释:1a在两次实例化过程中,只出现了1次,验证了静态代码块和静态变量在类加载的时候执行一次,后续不再执行。
32b出现了两次,跟代码中A a = new B();A b = new B();正好对应起来,父类成员变量->父类构造函数->(子类成员变量)->子类构造函数。
这个代码实例没有出现静态变量和子类成员变量,但是经过以上逻辑分析,我们已经很清楚这个执行过程了。