您的位置:首页 > 编程语言 > Java开发

java基础加强(类加载器)

2015-03-27 22:51 211 查看

类加载器

1、Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader

2、类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap,他是由C++编写的。

3、Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载器为其父级类加载。

public class ClassLoaderTest {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
System.out.println(ClassLoaderTest.class.getClassLoader().getClass()
.getName());
System.out.println(System.class.getClassLoader());
//结构为null,他是有BootStrap(引导程序)加载的,他是有c++语言编写的,所以他为null
ClassLoader loader = ClassLoaderTest.class.getClassLoader();
while(loader != null){
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
/*
* sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
null
*/
System.out.println(new ClassLoaderAttachment().toString());
Class clazz = new MyClassLoad("itcastlib").loadClass("ClassLoaderAttachment");
//ClassLoaderAttachment d1 = (ClassLoaderAttachment) clazz.newInstance();
}
}


类加载器之间的父子关系和管辖范围图



类加载器的委托机制:

1、当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

(1)首先当前线程的类加载器去加载线程中的第一个类。

(2)如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。

(3)还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

2、每个类加载器加载类时,又先委托给其上级类加载器。

当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?

面试题:能不能自己写个类,也叫java.lang.String?(考点:类加载器的委托机制)

答:可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String。由于在tomcat的web应用程序中,都是由webapp自己的类加载器先自己加载WEB-INF/classess目录中的类,然后才委托上级的类加载器加载,如果我们在tomcat的web应用程序中写一个java.lang.String,这时候Servlet程序加载的就是我们自己写的java.lang.String,但是这么干就会出很多潜在的问题,原来所有用了java.lang.String类的都将出现问题。

编写自己的类加载器

原因:由于特殊需求,我们可能需要自己写类加载器,加载我们制定的特定目录下的class文件或者jar包,我们自己写的类加载器可能会对class文件进行加密,这样,只有通过我们自己写的类加载器才能把class文件解密并加载。

相关知识讲解:

1.自定义的类加载器的必须继承ClassLoader

2.loadClass方法与findClass方法

3.defineClass方法

编程步骤:

1、编写一个对文件内容进行简单加密的程序。

2、编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。

3、编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: