计算机系统应用教程网站

网站首页 > 技术文章 正文

Java编程细节 java是怎么加载类的

btikc 2024-09-08 12:00:08 技术文章 19 ℃ 0 评论

庖丁解牛--Java的类加载机制

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

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

ClassNotFoundException

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

那么Java是怎么查找项目路径下的类的呢,看看下面这段代码

Alt text

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加载的

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。具体怎么实现呢?

明天我们会接着讲。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表