直接就在JDK8中用代码来验证吧。
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Printer {
private String s;
public Printer(String s) {
log.info("Printer 构造器: "+s);
this.s = s;
}
}
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Initial {
{
log.info("非静态块 nsb1");
}
static {
log.info("静态块 sb1");
}
public Initial() {
log.info("空参构造器");
nsf1 = new Printer("空参构造器 入参: " + "");
}
private Printer nsf1 = new Printer("非静态域 nsf1");
private static Printer sf1 = new Printer("静态域 sf1");
{
log.info("非静态块 nsb2");
}
static {
log.info("静态块 sb2");
}
public Initial(String s) {
log.info("带参构造器");
nsf2 = new Printer("带参构造器 入参: " + s);
}
private Printer nsf2 = new Printer("非静态域 nsf2");
private static Printer sf2 = new Printer("静态域 sf2");
public static void main(String[] args) {
new Initial();
}
}
main方法的执行结果打印如下:
静态块 sb1
Printer 构造器: 静态域 sf1
静态块 sb2
Printer 构造器: 静态域 sf2
非静态块 nsb1
Printer 构造器: 非静态域 nsf1
非静态块 nsb2
Printer 构造器: 非静态域 nsf2
空参构造器
Printer 构造器: 空参构造器 入参:
可以得知,一个类的对象的实例化时,其成员的加载顺序:
首先:静态成员(静态块/静态域,从上往下的顺序)
然后:非静态成员(非静态块/非静态域,从上往下的顺序)
最后:构造器
如果一个类它是继承父类的话,情况又是怎么样的呢?
先来个父类:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Father {
{
log.info("父类 非静态块 nsb1");
}
static {
log.info("父类 静态块 sb1");
}
public Father() {
log.info("父类 空参构造器");
nsf1 = new Printer("父类 空参构造器 入参: " + "");
}
private Printer nsf1 = new Printer("父类 非静态域 nsf1");
private static Printer sf1 = new Printer("父类 静态域 sf1");
{
log.info("父类 非静态块 nsb2");
}
static {
log.info("父类 静态块 sb2");
}
public Father(String s) {
log.info("父类 带参构造器");
nsf2 = new Printer("父类 带参构造器 入参: " + s);
}
private Printer nsf2 = new Printer("父类 非静态域 nsf2");
private static Printer sf2 = new Printer("父类 静态域 sf2");
}
接着还是之前的Initial这个类,唯一变化就是让它继承上面的Father类:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Initial extends Father {
{
log.info("非静态块 nsb1");
}
static {
log.info("静态块 sb1");
}
public Initial() {
log.info("空参构造器");
nsf1 = new Printer("空参构造器 入参: " + "");
}
private Printer nsf1 = new Printer("非静态域 nsf1");
private static Printer sf1 = new Printer("静态域 sf1");
{
log.info("非静态块 nsb2");
}
static {
log.info("静态块 sb2");
}
public Initial(String s) {
log.info("带参构造器");
nsf2 = new Printer("带参构造器 入参: " + s);
}
private Printer nsf2 = new Printer("非静态域 nsf2");
private static Printer sf2 = new Printer("静态域 sf2");
public static void main(String[] args) {
new Initial();
}
}
这次main方法的执行结果打印如下:
父类 静态块 sb1
Printer 构造器: 父类 静态域 sf1
父类 静态块 sb2
Printer 构造器: 父类 静态域 sf2
静态块 sb1
Printer 构造器: 静态域 sf1
静态块 sb2
Printer 构造器: 静态域 sf2
父类 非静态块 nsb1
Printer 构造器: 父类 非静态域 nsf1
父类 非静态块 nsb2
Printer 构造器: 父类 非静态域 nsf2
父类 空参构造器
Printer 构造器: 父类 空参构造器 入参:
非静态块 nsb1
Printer 构造器: 非静态域 nsf1
非静态块 nsb2
Printer 构造器: 非静态域 nsf2
空参构造器
Printer 构造器: 空参构造器 入参:
可以得知,一个类的对象的实例化时,其成员的加载顺序:
1:父类的静态成员(静态块/静态域,从上往下的顺序)
2:子类的静态成员(静态块/静态域,从上往下的顺序)
3:父类的非静态成员(非静态块/非静态域,从上往下的顺序)
4:父类的构造器
5:子类的非静态成员(非静态块/非静态域,从上往下的顺序)
6:子类的构造器