Java类加载器基础

  Java代码源文件被执行的过程是:.java文件经过javac.exe的编译后生成.class文件,.class文件经过java.exe被JVM加载之后会在其内部生成描述该.class文件的Class对象。而这些对象中封装着运行时的类型信息,虚拟机在运行功能的时候也是执行这些类型信息。


执行过程

三种类加载器

  Java中的类加载有三种,按加载顺序(指的是某class文件需要被加载时按以下顺序寻找应该加载它的加载器)如下:Bootstrap类加载器、Extension类加载器、Application类加载器。其中Bootstrap负责加载系统类,通常是从rt.jar文件中加载。Extension类加载器是从jre/lib/ext目录下加载“标准的拓展”。也就是说这俩类加载器是加载一些Java设计者为我们提供的类。而第三个Application类加载器是加载第三方的jar包和src下我们自己编写的类。
  除了这些理论性的东西之外,对于Java EE开发者来说类加载器最大的作用就是获得资源文件的类路径(class文件所在的路径)。获得类路径有三步,获得字节码对象、获得字节码对象的类加载器、获得资源的URL、获得URL中的路径部分。


资源文件的类路径

  看完这里例子后其实我们还有一个疑点:字节码对象应该获取谁的?答案是只要是通过Application类加载器加载的类就可以。比如小码农还有一个Second类,打印出来的是相同的效果。当然使用的时候一般使用其所在的类就可以了。


字节码对象的获取

  说到这里我们就必须得说一个问题,不是所有类都能通过getClassLoader()方法获得他的类加载器(获取不到返回null),只有Extension类加载器和Application类加载器能通过getClassLoader()方法获得它的类加载器。为什么呢?因为Bootstrap类加载器通常是使用C编写的,它没有对应任何的JClassLoader对象,而ExtClassLoader和AppClassLoader是使用Java写的Java类。


Bootstrap类加载器

  到这里,还剩下一个Extension类加载器没有演示过,下图演示一下。(如果读者在测试的时候遇到Access restriction的问题,把JRE移除再添加就可以)


ExtClassLoader

加载顺序演示

  首先把我们的测试程序打包成jar包,然后拷贝到jre/lib/ext下,这样再运行我们的类时由于先使用Extension类加载器加载,所以会运行jre/lib/ext的文件。如下图所示。


加载顺序

  我们获得资源的相对路径一般是为了进行InputStream读取,所以还需要距离实用还有一步读取。完整的操作如下:


读取properties文件

  然而Java的设计者就特别贴心了,不用我们这么麻烦的操作,它提供了一个getResourceAsStream()方法。


使用getResourceAsStream()

  而更贴心的是我们连获取类加载器这一步都可以省略,通过Class类对象就可以直接使用getResourceAsStream(),当然它在底层最终使用的还是类加载器的getResourceAsStream()。


Class对象使用getResourceAsStream()


Class对象使用getResourceAsStream()的底层代码

  最常用的功能的解析已经结束了,但在Java核心技术卷中把类记载这部分放在了“安全”这一章,这是由于类加载器在加载类到虚拟机中时会检查类的完整性。而且所有的类加载器都会负责控制代码运行安全的安全管理器类进行合作来保证Java的安全性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值