Java变量的初始化顺序:
静态变量或静态语句块----->实例变量或初始化语句块----->构造方法
(注:这里实例变量的初始化是在构造方法中第一条指令执行前执行的,注意并不是构造方法之前)
父类:
子类:
测试结果:
new C().println()执行顺序:
1、执行父类B的静态代码块( 输出qwe)
2、执行子类C的静态代码块( 输出123)
至此,父类和子类中所有的静态代码块执行结束,开始执行各类的实例变量初始化和构造函数
3、执行父类B的实例变量初始化操作(B类中i现值为123,s现值为234)
至此,父类的实例变量初始化完毕,开始执行父类的构造函数
4、执行父类B的构造函数( 输出”enter B()”)
5、执行父类B的init方法(因为方法的多态性,调用的是子类C的init方法)
6、父类调用子类C的init方法( 输出”enter C.init”,C类的i和s赋值为100,输出”exit C.init”)
7、父类调用子类C的init方法执行完毕,回到父类B中继续执行( 输出”exit B()”)
至此,父类的构造函数执行完毕,开始执行子类的实例变量初始化
8、执行子类C的inits方法,对实例变量S初始化( 输出”enter C.inits”,”exit C.inits”,C类中i现值为100,s现值为0)
至此,子类的实例变量初始化完毕,开始执行子类的构造函数
9、执行子类C的构造函数( 输出”enter C()”,”exit C()”)
至此,new C(),类C对象初始化完毕,开始执行对象.println()方法
10、执行对象的println()方法( 输出”enter C.println”,i现值:100,S现值:0,”exit C.println”)
至此,new C().println()语句执行完毕
后面两条测试语句和本例同理,要注意的是,方法有多态性但是属性没有,调用的是哪个类的对象的属性,就输出的是哪个对象中该属性的值</font>
@Autowired一定要等本类构造完成后,才能从外部引用设置进来
所以@Autowired的注入时间一定会晚于构造函数的执行时间。但在初始化变量的时候就使用了还没注入的bean,所以导致了NPE。如果在初始化其它变量时不使用这个要注入的bean,而是在以后的方法调用的时候去赋值,是可以使用这个bean的,因为那时类已初始化好,即已注入好了。