[Java SE] Java静态代码块与静态属性的执行顺序
序
- 最近有个需求,需要对日志框架进行动态注入一些配置。
- 这就涉及到了Java普通应用程序的启动顺序/生命周期。
Java普通应用程序,可以理解为 未接入spring框架的Java应用。
-
这不,就盯上了 通过 静态代码块来注入,需要在 静态属性' private final static Logger logger= LoggerFactory.getLogger(xxx.class)'之前执行。
-
这个试验是成功了。
(但最终没有采用这种方式,因static方案无法满足我从外部动态加载某些配置参数进来)
重要结论
先说结论,再去观察实验现象,印证结论。
-
静态变量初始化和静态代码块的执行顺序是:按照它们在类中出现的顺序进行的。
-
static 块的执行时机
类被加载了不一定就会执行静态代码块,只有一个类被主动使用时,静态代码才会被执行!
当一个类被主动使用时,Java虚拟就会对其初始化,如下六种情况为主动使用:
- 当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)
- 当调用某个类的静态方法时
- 当使用某个类或接口的静态字段时
- 当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时
- 当初始化某个子类时
- 当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类)
代码实验
实验1
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JavaStaticTest {
private final static String VAR = "xx";//0
static {
System.out.println("world!");//1
}
private final static Logger logger = getLogger();//2
public static void main(String[] args) {
System.out.println("hello");//4
}
public static Logger getLogger(){
System.out.println("Hahaha");//3
return LoggerFactory.getLogger(JavaStaticTest.class);
}
}
实验2
public class StaticOrder {
static {
System.out.println("Static Block 1");//1.1
}
static int a = initializeA();//2.1
static {
System.out.println("Static Block 2");//3
}
static int b = initializeB();
static int initializeA() {
System.out.println("Initializing A");//2.2
return 10;
}
static int initializeB() {
System.out.println("Initializing B");//4
return 20;
}
public static void main(String[] args) {
System.out.println("Main Method");//5
}
}
out
Static Block 1
Initializing A
Static Block 2
Initializing B
Main Method
X 参考文献
- 无
本文作者:
千千寰宇
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号