JVM java类的装载、链接、初始化

java从源文件到程序运行需要经历两个步骤
  • .java文件经过最初的编译成为.class字节码,成为机器识别的二进制语言。
  • .class文件由JVM解释成所对应不同的硬件平台操作系统能够执行的代码。
    (编译器是与平台无关,编译生成的中间码也与平台无关(一次编译,到处运行),中间码再由解释器解释执行,解释器是与平台相关的,也就是不同的平台需要不同的解释器.java程序也通过运行在不同jvm上实现跨平台)
解释有以下的三个步骤
  • 装载:通过classLoader 把字节码文件装载到内存中,程序只有加载到内存才能运行。创建对应类的实例,在堆区建立一个java.lang.Class对象。
  • 链接:链接又分为以下三个步骤
    • 验证:验证内存中的字节码文件是否符合jvm规范,符合规范的文件才能够在javm下运行
    • 准备: 将类的成员变量分配内存空间,初始化默认值。(虽然类的变量有初始值,但此时不会对变量进行初始化)(对于类的成员变量,不管程序有没有显式的进行初始化,Java虚拟机都会先自动给它初始化为默认值。但是局部变量,java虚拟机就不会对他进行默认初始化,所以声明时必须对它进行显示初始化)
    • 解析:为类、接口、方法、成员变量的符号引用定位直接引用。
  • 初始化:按照顺序执行静态代码块,将类的静态变量赋予正确的初始值(这个初始值是显示初始化的值,没有显示初始化的值还是系统为他分配的默认值),只有当类第一次主动使用时(new,反射,初始化子类等…)才会去初始化类
    1. 假如这个类还没有被加载和连接,那就先进行加载和连接。初始化一定在加载链接之后
    2. 如果父类还没有被初始化,那就先初始化父类。(接口的初始化,不会引起父类接口的初始化)
    3. 依次执行初始化语句。
      代码思考:
class Singleton {     

    public static Singleton singleton = new Singleton();     
    public static int a;     
    public static int b = 2;     

    private Singleton() {     
        super();     
        System.out.println("构造前"+a+"--"+b);
        a++;     
        b++;     
    }     

    public static Singleton GetInstence() {     
        return singleton;     
    }     

}     

public class MyTest {     

    /**    
     * @param args    
     */    
    public static void main(String[] args) {     
        Singleton mysingleton = Singleton.GetInstence();     
        System.out.println(mysingleton.a);     
        System.out.println(mysingleton.b);     
    }     

}    

一般都会得到的结论就是,a=1,b=3。但是正确的 运行完后答案是【构造前0–0,a=1,b=2。】
为什么呢?当你用到这个类时( Singleton mysingleton = Singleton.GetInstence(); ) 你才会去初始化这个类,初始化是有先后顺序的,根据代码首先初始化singleton对象( static Singleton singleton = new Singleton(); ),这个对象的变量还是jvm赋给的默认值,因为还没对a,b进行初始化(所以 a=0,b=0)。随后再去初始化a,b。 就将b设为了初始值0。
—如果将static Singleton singleton = new Singleton();的初始化放到a、b初始化之后,那么输出的结果是【构造前0–2,a=1,b=3】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值