java初始化加载类_Java 类的加载和初始化

直接从书上抄来的,自己写一遍加深印象

类的加载

加载就是通过指定的类全限定名,获取此类的二进制字节流(可以是clazz文件或者直接内存读取或者远程网络,jar包等),然后将此二进制字节流转化为方法区的数据结构,在内存中生成一个代表这个类的java.lang.Class对象。

java.lang.Class这个类用于维护目标类,包括读取字段 读取构造函数,读取方法,创建实例(newInstance)等等。

class对象可以通过Class.forName("java.lang.String")获取,或者直接String.class获取,

或者"java.lang.String".getClass(),注意getClass方法是java.lang.Object中定义的,属于native方法

定义的类不一定是第一次使用的时候的才加载也可以预先加载,java虚拟机桓范允许系统预先加载某些类。

当类被加载后,系统会生成对应的class对象,接着进入连接阶段。连接阶段负责把类的二进制数据合并到jre中,具体分三阶段

1.验证文件是否合法,不会危害虚拟机的安全

2.为类的变量分配内存 设置默认值

3.将类的二进制数据中的符号引用替换成直接引用

类的初始化

在初始化阶段,主要对类变量执行初始化。将常量池(里面存储了我们编写的java类的类和接口的全限定名,字段的名称和描述符)中的符号引用转换为直接引用的过程。设置初始化一般有2种方法,1是声明的时候直接赋值,2是使用静态代码块

如果这个类还存在父类,那么先需要初始化直接父类,所以jvm最先初始化Object

如果类包含初始化语句则执行

什么时候会初始化?

1.创建实例 比如new 反射创建实例 反序列化等

2.调用某个类的方法(静态的)

3.访问某个类或接口的类变量

4.使用反射创建某个类或接口的class对象,例如class.forName("xx")

5.初始化某个类的子类 子类的所有父类都会初始化

注意一个final类型的类变量,如果编译时就确定了具体的指,那么这个类变量相当于宏变量,编译器会执行优化,调用这个变量的地方直接替换成该值,这个变量相当于不存在了。变量调用自然不会导致该类的初始化。

ClassLoader.loadClass()只会导致类被加载,Class.forName()才会执行类的初始化

类加载器

类加载器负责加载所有的类,系统为所有被载入内存的类生成对应的java.lang.Class实例。一个一旦被加载,则不会被再次载入了。每个被载入内存的类,都有一个唯一标识(类的全限定类名和其类加载器)

加载器规则

1.加载一个类时,该类所依赖和引用的其他类都由改类的加载器负责载入

2.如果一个类存在父类,则优先尝试使用父类的加载器加载该类

3.所有被载入的类都会被缓存,读取类的时候,会优先使用缓存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值