Java面试问题之十一
请问什么是Java类加载的父亲委托(Parent Delegation)机制,举例说明一下类加载的委托机制的运行过程以及基于父亲委托机制实现的类加载器的设计目的。
答:Java类加载的父亲委托机制是指,当程序请求加载类的时候,当前的加载器总是委托其父加载器帮其完成类的加载工作。在父亲委托机制中,各个加载器按照父子关系形成了树形结果,除了根类加载器以外,其余的类加载器都有且仅有一个父加载器。
举一个例子来说,假如有两个类加载器,它们分别是loader1和loader2,其中loader1是loader2的父加载器。现在在代码中出现下列语句要求加载器loader2加载一个Sample类:
Class sampleClass = loader2.loadClass("Sample");
那么整个委托过程是这样的:loader2首先从自己的命名空间中查找Sample类是否已经被加载过了,如果已经加载过,就直接返回代表Sample类的Class对象的引用。如果Sample类没有被加载,loader2首先请求loader1代之加载,loader1再请求系统类加载器代之加载,系统加载器再请求扩展类加载器代之加载,而扩展类加载器再请求根类加载器代之加载。如果根类加载器和扩展类加载器都无法加载Sample类,则系统类加载器会尝试加载Sample类,如果加载成功,则将Sample类所对应的Class对象的引用返回给loader1,loader1再将引用返回给loader2,从而成功将Sample类加载进虚拟机中。如果系统类加载器还是不能加载Sample类,则loader1会尝试加载Sample类。倘若loader1还是不能成功加载Sample类,那么现在只能依靠loader2自己来尝试加载这个类了,加载失败则抛出ClassNotFoundException异常。
父亲委托机制提出的意图很大程度上是考虑软件系统的安全问题。因为在这种机制下,用户定义的类加载器不可能加载应该由其父加载器加载的可靠类,从而防止不可靠甚至是恶意的代码代替由父加载器的可靠代码。比如说,在这种机制下用户定义的类加载器都不可能加载包含由恶意代码的java.lang.Object类。