1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > [转载] Java中静态成员变量 静态代码块 静态内部类何时被初始化?

[转载] Java中静态成员变量 静态代码块 静态内部类何时被初始化?

时间:2019-09-01 03:05:52

相关推荐

[转载] Java中静态成员变量 静态代码块 静态内部类何时被初始化?

参考链接: Java中的初始化程序块Initializer Block

关于这个问题,本文不扯理论,直接上代码,通过结果来验证结论,废话少说,测试代码如下:

public class StaticTest {

public static StaticMember staticMember = new StaticMember();

static {

System.out.println("static code initializer ");

}

private static class InnerClass {

private static StaticTest staticTest = new StaticTest("load from InnerClass");

}

public StaticTest() {

}

public StaticTest(String a) {

System.out.println(a);

}

public static void f(){

}

public void d(){

}

public static void e(){

InnerClass.staticTest.d();

}

}

public class StaticMember {

public StaticMember(){

System.out.println("StaticMember");

}

}

在StaticTest 测试类中我写了三种静态域分别是静态成员变量,静态代码块以及静态内部类,下面通过不同的case测试上面三种静态域何时被初始化。 测试case代码:

public class Main {

static boolean flg;

public static void main(String[] args) {

/**case1**/

//不会执行静态代码块, 静态成员变量不会初始化, 也不会加载静态内部类

String simpleName = StaticTest.class.getSimpleName();

/**case2**/

//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类

//输出 StaticMember

// static code initializer

StaticMember staticMember = StaticTest.staticMember;

/**case3**/

//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类

//输出 StaticMember

// static code initializer

new StaticTest();

/**case4**/

//会执行静态代码块, 静态成员变量会初始化, 不会加载静态内部类

//输出 StaticMember

// static code initializer

StaticTest.f();

/**case5**/

//不会执行静态代码块, 静态成员变量不会初始化, 也不会加载静态内部类

if (flg) {

test();

}

/**case6**/

//会执行静态代码块, 静态成员变量会初始化, 同时加载静态内部类

// 输出:StaticMember

// static code initializer

// load from InnerClass

StaticTest.e();

}

private static void test(){

StaticTest.f();

StaticTest.e();

}

}

通过上面每一种代码测试case的输出结果,可以得出如下结论:

静态成员变量和静态代码块(static{})只有在类被调用的时候才会初始化。 这里是指在运行时真正被使用到才会被初始化,如果是在编译时被使用到,但在运行时没有使用到也不会被初始化,比如上面的case5。静态内部类只有当被外部类调用到的时候才会初始化。 这里也是指在运行时,也就是说不在于你在编辑器中有没有写调用的代码,而是你写的这段调用代码运行时是否会被真正执行到。在只使用了外部类,但是没有使用内部类的情况下,内部类里面的东西不会被初始化。

关于case1的情况,直接引用StaticTest.class不会初始化静态变量和静态代码块,而直接new StaticTest()就会,为什么呢?因为JVM在加载类的过程中分为五个阶段:加载、验证、准备、解析、初始化,StaticTest.class的方式发生在第一个阶段,这个阶段会在Java堆中创建java.lang.Class的实例,而变量和静态块是发生在最后一个初始化的阶段,具体参考:Java虚拟机 类加载的过程, Chapter 5. Loading, Linking, and Initializing

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。