前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java是怎么加载类的

Java是怎么加载类的

作者头像
PhoenixZheng
发布2018-08-07 16:41:05
6820
发布2018-08-07 16:41:05
举报
庖丁解牛--Java的类加载机制

Java的类加载机制是最容易被忽略的知识,不管是基础,还是往高级开发进阶,都需要了解类的加载机制。

今天从Java中常见的异常 ClassNotFoundException说起,来说说"双亲委托"

ClassNotFoundException

我们知道发生这个异常的原因是找不到某个类,但具体是为什么找不到这个类呢?当然最简单的就是当前项目路径下没有这个类。 那么Java是怎么查找项目路径下的类的呢,看看下面这段代码

Alt text

代码语言:javascript
复制
public class Ming {

  public static void main(String[] args) {
    System.out.println("Ming looking for socker");
    Socker socker = new Socker();
  }
}

编译运行

$ javac Ming.java Ming.java:7: 错误: 找不到符号 Socker socker = new Socker(); ^ 符号: 类 Socker 位置: 类 Ming Ming.java:7: 错误: 找不到符号 Socker socker = new Socker(); ^ 符号: 类 Socker 位置: 类 Ming 2 个错误

错误很明显,Java在MingHouse下面找不到Socker类,因为Scoker在另一个路径WangHouse下面。眼尖的同学应该会留意到System.out这句日志方法没有报错,说明Java找到了这个类。可是我们没有import,也没有在目录下有这个类,它是系统类,不过Java是怎么找到它的还是得说明一下。

双亲委托

Java类的加载是由几个ClassLoader进行的,他们分别是 · BootStrapClassLoader · ExtensionClassLoader · AppClassLoader 他们之间的区别呢,可以简单理解为加载路径的不同。BootStrap负责加载系统核心类,Extension负责加载扩展类,而AppClassLoader负责加载当前app下面的所有jar和class文件。

还记得JAVA_HOME这个常量吗?通常配置Java环境第一件事就是设置这个常量,因为这样ExtensionClassLoader才能去找到 jre/lib/ext/ 下的jar和class。他们的加载顺序是怎样的呢?就上面代码的例子来说

小明:爸!我找不到袜子! 小明爸爸:找你妈去。 小明:妈!我找不到袜子! 小明妈妈:我也找不到!

在这个例子里, · 小明->AppClassLoader · 小明爸爸->ExtensionClassLoader · 小明妈妈->BootStrapClassLoader 这就是双亲委托了。

我们可以用这个代码看看当前类是哪个ClassLoader加载的

代码语言:javascript
复制
public class Ming {
  public static void main(String[] args) {
    System.out.println("class loader : " + Ming.class.getClassLoader());
    Socker socker = new Socker();
  }
}

输出说明,Ming这个类是由AppClassLoader加载的

class loader : AppClassLoader

总的说,AppClassLoader会现在当前的classpath下找,找不到就问父级ExtensionClassLoader要,再找不到,ExtensionClassLoader就会管BootStrapClassLoader要。实在找不到就会ClassNotFound了.

到这里应该就明白,System类是由ExtensionClassLoader去查找加载,因为已经在JAVA_HOME里有,所以加载的到,而Socker不在ClassLoader的class path中,所以加载不到。

举一反三

按照双亲委托的机制,我们是没法找到在WangHouse里的Socker的。因为WangHouse的路径并不在我们ClassLoader里。

但是!

我们还是有办法在不import的情况下,通过自定义ClassLoader的方式,来找到WangHouse里的Socker。具体怎么实现呢?

明天我们会接着讲。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android每日一讲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 庖丁解牛--Java的类加载机制
  • ClassNotFoundException
  • 双亲委托
  • 举一反三
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档