类加载

  本文聊一聊类加载器的应用。我们知道,java文件经过javac指令的编译后会生成class文件,class文件经过java指令被JVM加载之后会在其内部生成描述该class文件的的Class对象。在这个过程中,java指令起的就是类加载的作用。

执行过程

  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类加载器没有演示过,下图演示一下。不过Extension类加载器的演示比较困难,小码农在jre/lib/ext下找了好几个类都不能使用,所以采取了一种投机取巧的方法来演示。首先把我们的测试程序打包成jar包,然后拷贝到jre/lib/ext下,这样再运行我们的类时由于先使用Extension类加载器加载,所以会运行jre/lib/ext的文件。如下图所示。

Extension类加载器

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

读取properties文件

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

使用getResourceAsStream()

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

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 作为一名AFP(金融理财师)持证人,今天不是来做广告的,而只是想谈谈个人的一点感想。我既没有在理财生涯博得巨...
    向日葵小妞2016阅读 1,544评论 0 0
  • 蒲公英的约定,以四海为家。 ——题记 终于,我停下了自己几经辗转流浪的脚步,延缓这场无尽的旅程。 在这场旅行中,我...
    佚幻薰衣草阅读 1,792评论 0 1
  • 新官上任,需要改变,一是上级领导的信任和期待,二是对自己的肯定。做哪些改变是有效的才是新官上任的难度。了解,沟通,...
    孙倩倩Rela阅读 431评论 0 0

友情链接更多精彩内容