1. 类加载

类加载

1.类加载

在Java代码中, 类型加载、连接和初始化过程 都是在程序运行期间完成的。

  • 类型: 这里指的是Class类,比如有一个User对象,而这里的类型指的是User.class,而不是 new出来的User对象。
  • 加载: 将指定class文件,或远程url文件获取,然后加载到内存中
  • 连接: 确定类与类之间的引用关系,验证和检验class文件的准确性。这里分为三个阶段
  • 初始化: 对加载的类中的静态变量赋值正确的初始化值的过程

  • 程序运行期间: 意思是加载、连接、初始化过程都是在Runtime运行时完成的,不是静态编译时完成的。

1.1 类加载--连接过程又分为三个阶段

  1. 验证: 验证class文件的正确性,虽然大多数的class文件都是通过javac编译而来,但是编译后的class文件是可以再次被文本编辑器手动修改的。
  2. 准备: 为类型中的静态变量分配内存,并初始化赋值默认值

    注意举例:public static int a = 1; 针对该变量a,在该阶段,会为a分配内存,且初始化默认值。
    这里不会解析到 a =1,这里只会根据数据类型来决定默认值,即int--0,double--0.0,boolean--false,object--null,等,至于执行 a = 1 的操作,是在后续的初始化阶段完成。

  3. 解析: 将类中的符号引用转换成直接引用

1.2 类加载的几种途径

类加载指class文件的二进制数据加载到内存中,将其放入到方法区中,并且分配内存,创建一个 java.lang.Class 对象(jvm规范并没有要求Class对象放在哪里,HotSpot将其放入到方法区内),用来封装类在方法区的数据结构,这就是不管该类有多少个实例对象,都只会有一个Class对象的原因。

类加载的途径:

  1. 本地的class文件,例如classpath下的class文件
  2. 通过网络下载class文件
  3. 从zip,jar包等归档文件中提取class文件
  4. 从专有的数据库中加载class文件
  5. 将源文件编译成class文件,例如动态代理,和aop切面

1.3 总结点

  1. 对于静态变量来说,只有直接定义了静态变量字段的类,才会被初始化
  2. 在一个类初始化的时候,必须是其父类先被初始化完毕

2.类加载器

jvm加载class文件,解析class参数到内存中,这过程依赖类加载器来实现。

3.导致jvm虚拟机生命周期结束的四种原因

  1. 手动调用System.exit()
  2. 程序正常执行结束
  3. 程序遇到异常,导致程序终止
  4. 操作系统异常,导致jvm停止

4.类的主动使用和被动使用

java类或接口只要在首次主动使用的情况才会初始化他们

4.1 主动使用的七种场景

  1. 实例化对象
  2. 调用类的静态变量,设置静态变量赋值
  3. 调用类的静态方法
  4. 使用反射处理类,例如使用Class.forName来实例化对象
  5. 针对继承父子关系时,实例化子类的同时,必然会主动使用其父类
  6. 被jvm虚拟机认定为启动类的类,例如执行当前main的类
  7. 针对jdk1.7之后,支持动态语言调用处理的结果对应的类没有初始化的,则初始化

4.2 被动使用

不是主动使用的都为被动使用,被动使用的特点是都不会导致类的初始化。

猜你喜欢

转载自www.cnblogs.com/duguxiaobiao/p/12091931.html