微科社区,轻松开发从此开始! 请登陆 免费注册

微科社区

当前位置:首页 > Java平台 > 认证考试 >

Java认证考试:深入理解Java加载类的机制

时间:2017-01-22 04:01  浏览:努力统计中...
这里从三个方面讲述java classloader 1、翻译一下classloader的相关技术文章(来自Core Java第二卷的Chapter 9. Security),由于我的英文水平有限,难免有不合适,请大家指出。 2、将从web应用出

  这里从三个方面讲述java classloader

1、翻译一下classloader的相关技术文章(来自Core Java第二卷的Chapter 9. Security),由于我的英文水平有限,难免有不合适,请大家指出。

2、将从web应用出发模拟一下web应用的classloader(这节是重点)

3、通过测试2实现的classloader来加深理解

  以下是翻译的关于ClassLoader介绍

   ClassLoader

  JAVA编译器把源代码转换成一个假想机器(就是我们所说的虚拟机)的语言。虚拟机指令被保存在class后缀的文件里。每一个类文件包含类和接口的定义以及实现代码。这些类文件必须被一个程序解释,这个程序能够把虚拟机的指令翻译成宿主机的机器语言。

  注意:虚拟机只加载执行一个程序所需要的类文件。举个例子,比如执行MyProgram.class,虚拟机运行的步骤如下:

1、虚拟机有一个加载类文件的机制,比如,从硬盘读取文件或者就网络获得;虚拟机用这个机制加载MyProgram的类文件

2、如果MyProgram有一个实例变量或者是超类,那么实例变量和超类的类文件也被加载。(加载一个类所依赖的所有类的过程叫做resolving the class--》自己理解吧)

3、然后虚拟机执行MyProgram的main方法(因为是静态方法,所以不需要new MyProgram的实例)

4、如果main 方法或者main方法调用的方法需要其他的类的话,这些类也被加载。

  类加载机制不是仅仅用一个类加载器,任何一个java程序至少有以下三个类加载器(为了不影响大家的理解,这里我就不翻译这三个类加载器的名称了)

  The bootstrap class loader:加载系统类(有代表性的,jdk的rt.jar里的类),他是虚拟机的必要组成部分,并且一般是用C实现的。

  也有类加载器对象(就是指具体的一个类加载器)不关联bootstrap class loader,比如String.class.getClassLoader()返回null.

  The extension class loader:加载jre/lib/ext目录下的class,你可以把你的jar文件放到这个目录,extension class loader将会加载到jar里面的类,即使你不设置classpath.(一些人建议使用这个机制以让你不受classpath的烦扰,不过注意以下的警告)The system class loader (有时也叫应用程序加载器):加载应用程序类。

  他主要加载classpath目录和jar/zip文件里的class,通过设置CLASSPATH环境变量或者是运行java的时候用 [-classpath]选项指定classpath在SUN的java实现里,the extension and system class loaders都是用java实现的,他们都是URLClassLoader类的实例。

  警告:如果你把jar文件放到jre/lib/ext目录下,并且你的jar文件中的类需要加载一个不是system or extension的类的话,你将遇到麻烦。扩展类加载器不使用类路径。如果你想把类放到jre/lib/ext下进行管理的话,请牢记这一点。

  ==》怎么理解这一点:也就是说如果你把自己的x.jar放到jre/lib/ext下的话,如果你自己的x.jar里的class要用到不在x.jar里也不在jre/lib/ext的类的话,会导致类加载不了。不难想象吧,因为你x.jar里的类是由extension class loader加载的,他不会加载classpath路径下的类。

  警告:把jar文件放到jre/lib/ext目录下,还有第二个缺陷:有时侯,程序员忘记了他很久以前放在这个目录下的类文件。

  当class loader似乎忽略了类路径(其实没有,因为类加载总是先让父的类加载器加载类,只有父的类加载器加载不了的话才由自己来加载,“extension class loader是system class loader的父,因此。..”),而加载了放在扩展目录下的遗忘已久的类的时候,他们就会迷惑不解。

  class loader有父子关系,bootstrap class loader以外的每一个class loader都有一个父的类加载器。

  类加载器会给父的加载器一个机会加载任何给定的类,如果父加载器加载失败的话自身才去加载。

  举个例子,当系统class loader被要求加载一个系统类的时候(比如,java.util.ArrayList),那么,首先需要extension class loader加载,而extension class loader又先让bootstrap class loader,最终由bootstrap class loader查找并且加载了rt.jar,其他任何类加载器不需要再搜索。

  注意:当实现一个类加载器的时候,你应该总是授权父加载器去加载类。否则,将会有一些潜在的安全隐患:自定义的类加载器可能避开重要的安全检查,意外地加载了系统类。

  Applets, servlets, and RMI stubs是用户自定义的类加载器加载的。你甚至可以根据自己的需要写自己的类加载器。

  这种方式允许你在传字节码给虚拟机之前实现特殊的安全检查。比如,你可以写一个类加载器拒绝加载没有用“paid for”表示的类。下一节将展示这么去实现。

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线------