Java之类加载器

1. 类加载器是什么?

当我们在程序中调用一个类的方法或者new一个类的对象时,JVM必须先把.java文件编译后的.class文件加载进去才行。
类加载器就是用来加载.class文件的工具。

2. 类加载器有几种?

  1. 启动(Bootstrap)类加载器
    它负责将 <JAVA_HOME>/lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar包加载到内存中,只加载特定名称的jar和特定名称的包。对jar包名称(rt.jar)和包名(java.javax.sun.)都有严格要求。
  2. 扩展(Extension)类加载器
    它负责加载<JAVA_HOME>/lib/ext目录下或者由系统变量-Djava.ext.dir指定的类库。
  3. 应用(Application)类加载器
    它负责加载java -classpath或-D java.class.path 指定的类库,也就是我们经常用到的classpath路径。

类加载器种类

3. 类加载器的机制是什么?

JVM采用双亲委派的类加载机制。应用类加载器(AppClassLoader)用到某一个类时,自己先不加载,先委派给扩展类加载器(ExtClassLoader)来加载,扩展类加载器(ExtClassLoader)再先委派给启动类加载器BootstrapClassLoader)加载,上一级找不到class的话,自己再加载。
这种经过两次委派的机制称为双亲委派机制,这里的双亲并不是指继承关系,指的是逻辑上的亲子关系。

4. 为什么要采用双亲委派?

1.为了安全,核心class只能由启动类加载器来加载,随意篡改的核心class文件无法加载进jvm。
2. 防止重复加载class,java中的class全名中是包含类加载器名称的,一个类加载器加载的class所new出来的对象 用instansof type来和另一个类加载器加载的class比较的话,结果是false。
比如,Aclassloader 加载进来一个 Demo.class文件,然后new 了一个 demo对象
Bclassloader也加载同一个Demo.class文件,然后 System.out.println(demo instanceof B.Demo.class),结果为false

5. 类加载的步骤?

类加载的步骤

  1. 加载: 加载class文件。
  2. 验证: 验证class文件,保证二进制字节码在结构上的正确性。
  3. 准备: 准备阶段主要是创建静态域,分配空间,给这些域设默认值。
  4. 解析
    解析的过程就是对类中的接口、类、方法、变量的符号引用进行解析并定位,解析成直接引用(符号引用就是编码是用字符串表示某个变量、接口的位置,直接引用就是根据符号引用翻译出来的地址),并保证这些类被正确的找到。
  5. 初始化: 创建class对象。
    1. 初始化时机
      1. 创建对象的实例:我们new对象的时候,会引发类的初始化,前提是这个类没有被初始化
      2. 调用类的静态属性或者为静态属性赋值
      3. 调用类的静态方法
      4. 通过class文件反射创建对象
      5. 初始化一个类的子类:使用子类的时候先初始化父类
      6. java虚拟机启动时被标记为启动类的类:就是我们的main方法所在的类
      7. 在编译的时候能确定下来的静态变量(编译常量),不会对类进行初始化:调用某个类的static final变量不会初始化类,static final常量是在编译阶段就初始化好了的
      8. 如果这个类有父类并且这个父类没有被初始化,则先初始化父类.
      9. 如果类中存在初始化语句,依次执行初始化语句.
    2. 初始化步骤
      1. 父类的静态属性
      2. 父类的静态代码块
      3. 子类的静态属性
      4. 子类的静态代码块
      5. 父类的非静态属性
      6. 父类的非静态代码块
      7. 父类构造方法
      8. 子类非静态属性
      9. 子类非静态代码块
      10. 子类构造方法

6. 怎么破坏双亲委派?

  1. 线程上下文类加载器
    Java中提倡面向接口编程,所有Java有很多服务提供者接口(Service Provider Interface,SPI),这些接口都属于Java的核心类库,但是它们的实现类都是第三方提供的,属于应用类库。那么启动类加载器怎么加载这些实现类呢。为了解决这个问题,Java引入了线程上下文类加载器(ContextClassLoader),默认为应用类加载器。
    线程上下文类加载器

  2. 插件热插拔系统
    插件热插拔系统的类加载机制不是树状结构,每个插件都有独立的类加载器,不属于双亲委派。

  3. 自定义classloader
    自定义的classloader可以不遵循双擎委派规则。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值