java 虚拟机【一个demo 学习--类加载 (一)】

package com.study;

class Singleton {
    private static Singleton singleton = new Singleton();
    public static int count1;
    public static int count2 = 0;
    private Singleton() {
        count1++;
        count2++;
    }
    public static Singleton getSingleton() {
        return singleton;
    }
}

public class MaiTest {

    public static void main(String[] args) {
        Singleton singleton = Singleton.getSingleton();
        System.out.println(singleton.count1);
        System.out.println(singleton.count2);
    }
}


一个简单的程序,大家猜一下运行结果?   可能很多人觉得 结果是 输出 两个 1 ,但其实结果是  1、0

下面我们学习一下,整个 jvm 是如何加载 java 文件的

1 (class 变量加载流程)

类执行之前,有三个步骤:加载   连接  初始化

 

1 加载,查找并加载 类的二进制数据(加载到内存中),类加载器将,程序的 .class 文件加载到内存中

2 连接,验证  确保加载的正确性  // 文件是否正确,class文件也可能是 用户自己伪造的 class 文件,不是通过javac 生成的

              准备 为类的静态变量 分配内存,并将其 初始化为默认值 // 类似 static int i 这种,其实是初始化 变量,然后赋值为0

              解析  类中符号引用 转换为直接引用// 类B中调用A 的方法,hello ,B中会new 一个A 的对象,代码中就用 a 调用方法,但 其实 a 这个值一个符号引用,程序是不识别的,解析中,a 会变成一个 指向A 的指针,这样程序才能执行

 

3 初始化 为类的静态变量赋予正常的初始值// 给静态变量赋值

执行流程如下:           

 

 

eq:  举例解释,比如  代码 public static int count1=1;

这个代码其实 分两个步骤,第一 是静态变量初始化, 方法区中分配  一块 区域,存储 count1 此时它的值为0

第二,就是赋值阶段,将数字1 赋值给 count1

 

2  类何时被初始化

java 程序对类的使用分两种: 主动使用,被动使用,java 程序对类 首次主动使用的时候,才会进行初始化

主动使用分为六种:

1   new A

2  A.count=1

3  A.sayHello()

4 反射  Class.forName(com.test.MyTest)

5 初始化类的子类

6 java 虚拟机启动的时候 标明启动类,  java MyTest

 

3 类加载的最终产物  堆区的 class 对象

class 对象 封装了 类在方法区的数据结构,并且向java 程序员 提供了 访问方法区内的数据结构接口

何为类加载: 类加载 就是将 .class 文件中的二进制数据 读到内存中,放到 运行时数据区的方法区中,然后在 堆区创建一个 Class 对象,用了封装 类在方法区内 的数据结构

 

类加载过程如下:

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值