反射中所涉及的类的内存加载分析

java的内存分析

  • 先上一张图看看大纲:
    在这里插入图片描述

类的加载过程

  • 当程序要使用某个类时,如果该类没有被加载在内存中,则该类要经过以下三个步骤进行初始化:
    1. 类的加载: 将类的对应的class文件读入内存中,并为其创建一个java.lang.Class对象,该过程由类加载器完成。值得注意的是一个类或者一个对象只会创建一个对应的java.lang.Class对象
    2. 类的链接:将java类的二进制代码合并到JVM的运行环境中去,首先对代码的准确性进行验证,再者准备阶段,为static分配内存和设置默认值。这也是static修饰符修饰的变量或方法可以直接使用的原因,最后是对引用类型的转换,将自己定义的类,转换为真实的引用类型。
    3. 初始化:JVM虚拟机通过执行构造器()方法的过程,将所有的类变量赋值的过程和static修饰的静态代码块的语句合并生成,并且在初始化一个类时会去考虑类的父类是否初始化,若父类没有初始化则对父类进行初始化。

使用一个实际的例子来模拟类的加载过程

package com.reflection;
//处理类的加载和内存分析
public class Demo03 {
    public static void main(String[] args) {
        //创建对象
        A a = new A();
        //直接调用静态方法
        System.out.println(A.m);
    }
}
//创建一个类,创建对应的方法来便于分析内存的变化
class  A{
    //创建静态代码块
    static {
        System.out.println("A类静态代码块的初始化");
        m=300;//因为静态变量是在类创建时与类一同创建的所有,在这m可以直接使用
    }
    //创建一个静态变量
    static  int m=100;
    //创建无参构造

    public A() {
        System.out.println("A类的无参构造初始化");
    }
}

  • 画图分析:
    在这里插入图片描述
  • 为什么m=100:
    在这里插入图片描述
  • 原因解释:
/*1.内存加载,一个类产生一个对应的Class对象
  2.链接:m初始值=0
  3.初始化:
  	调用<clinit>(){
  			//将所有类的变量的赋值和static的初始化合并
  			System.out.println("A类静态代码块的初始化");
        	m=300;
        	//因为静态变量是在类创建时与类一同创建的所有,在这m可以直接使用
        	static  int m=100;
  		}

==由上可知:==在A类静态代码块的初始化输出后对m进行了第一次赋值,m=300,随后又对m第二次赋值,m=100。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值