• 类加载机制


    首先看一段代码,想想下面的代码输出结果是什么:

    /**
     * 
     * @author vincent_duan
     * 
     */
    public class LoadingTest {
        public static LoadingTest obj = new LoadingTest();
        public static int val1;
        public static int val2=0;
    
        public LoadingTest() {
            val1 = 10;
            val2 = val1;
            System.out.println("before val1->" + val1);
            System.out.println("before val2->" + val2);
        }
        
    
        public static void main(String[] args) {
            System.out.println("after val1->"+val1);
            System.out.println("after val2->"+val2);
        }
    }

    程序输出如下:

    before val1->10
    before val2->10
    after val1->10
    after val2->0

      上述代码示例中,如果大家不信心的话,肯定会认为在main()方法中打印的Loading类的静态变量val1和val2的值都为10;但实际上程序最终输出的结果却是val1等于10,而val2等于0。在Loading类的构造方法中,尽管已经将静态变量val1和val2都显式赋值为10了,并且在构造方法中所打印的结果也的确为10,那么为什么会与main()方法中输出的结果不一致呢?

      如果将上述代码的位置稍作调整后,程序最终的输出结果是否又会产生变化呢?

      public static int val1;
        public static int val2=0;
        public static LoadingTest obj = new LoadingTest();

    程序输出如下:

    before val1->10
    before val2->10
    after val1->10
    after val2->10

      将声明静态变量obj的代码位置放在声明静态变量val2之后,程序最终的输出结果就跟预期的值一致了,这又是为什么呢?简单来说,当类加载器将Loading类加载进JVM内部后,会在方法区中生成一个与该类型对应的java.lang.Class对象实例,当进入到准备阶段时,JVM便会为Loading类中的3个静态变量分配内存空间,并为其设置初始值(val1和val2的初始值为0,而obj的初始值为null)。当经历到类加载过程中的初始化阶段时,程序最终的输出结果就会和代码的执行顺序有关了。在第一段代码中,静态变量obj是优先初始化的,那么JVM将会执行到其构造方法中,并覆盖掉静态变量val1和val2之前持有的初始值,也就是说,初始化静态变量obj后,val1和val2所持有的值都是10.接下来JVM会检查静态变量val1是否也需要执行初始化,由于val1并没有显示地指定进行赋值操作,因此将会直接跳转到静态变量val2上,这里就非常关键了。尽管之前指定了value2所持有的值为10,但当执行到val2=0时等于又重新对静态变量val2显式执行了一次赋值操作,也就是说,当前赋值操作将会覆盖掉之前在构造方法中的复制操作,这就是为什么val2的输出结果为0,而非10的原因。在将代码的执行顺序进行调换,尽管val2同样也经历过2次赋值操作,但最后一次赋予的值却是10,所以程序最终的输出结果就跟预期一致。

  • 相关阅读:
    软件项目“免坑”指南
    软件项目质量保证——编码规范
    从Web借鉴UI设计
    C#学习笔记——面向对象、面向组件以及类型基础
    关系数据库设计
    Winform开发框架之插件化应用框架实现
    桌面程序界面设计分享
    2-Bom
    1-简介
    测试
  • 原文地址:https://www.cnblogs.com/vincent4code/p/4854091.html
Copyright © 2020-2023  润新知