Classloader 类加载器,
用来加载 Java 类到 Java 虚拟机中。与普通程序不同的是。
Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java 虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。
java应用环境中不同的class分别由不同的ClassLoader负责加载。
一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:
Bootstrap ClassLoader负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等;
Extension ClassLoader负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class;
App ClassLoader负责加载当前java应用的classpath中的所有类。
其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。
Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系如下:
Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。
但是这并不是继承关系,只是语义上的定义,基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。
可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,因为它不是java class所以Extension ClassLoader的getParent方法返回的是NULL。
Class类中的方法:
1、URL getResource(String name)。
查找带有给定名称的资源。
如果在eclipse中编写并运行。
参数name为"","."时
file:/D:/JAVA%20IDE/eclipse3.2/work/MyTest/bin/com/hss/load/。
为"/"时
file:/C:/Program%20Files/Java/jre1.6.0_04/lib/ext/classes/。
2、InputStream getResourceAsStream(String name)。
查找具有给定名称的资源。
与1类似,只是形式不同
非常奇怪的是如果不用IDE,而只将文件放于硬盘的一处,得到的结果只是(无论是",".")
file:/C:/Program%20Files/Java/jre1.6.0_04/lib/ext/classes/。
ClassLoader类中的方法。
1、URL getResource(String name)。
查找具有给定名称的资源。
参数name为"","."时
ur1:file:/C:/Program%20Files/Java/jre1.6.0_04/lib/ext/classes/。
须注意的是该classloader是系统类加载器,其他加载器也一样。
2、InputStream getResourceAsStream(String name)。
返回读取指定资源的输入流。
3、Enumeration<URL> getResources(String name)。
查找所有给定名称的资源。
4、static URL getSystemResource(String name)。
从用来加载类的搜索路径中查找具有指定名称的资源。
name只能是"",或者".",否则得到的是null。
输出结果是 file:/C:/Program%20Files/Java/jre1.6.0_04/lib/ext/classes/。
5、static InputStream getSystemResourceAsStream(String name)。
从用来加载类的搜索路径打开具有指定名称的资源,以读取该资源。
以4相似,只是返回的是InputStream。
6、static Enumeration<URL> getSystemResources(String name)。
从用来加载类的搜索路径中查找所有具有指定名称的资源。
name只能是"",或者".",否则得到的是null。
输出结果是 file:/C:/Program%20Files/Java/jre1.6.0_04/lib/ext/classes/,
file:/D:/JAVA%20IDE/eclipse3.2/work/MyTest/bin/(测试类的class文件位于此目录)
总结:一般使用Class的getResource("/")获取当前类路径(包所在的顶层目录),使用getResource("")获取当前类的具体存放路径(具体到包目录的最底层如com.hss.servlet.MyServlet时,获取的路径将是com/hss/servlet)。
比较典型的自定义classloader使用情况就是给类加密。java编译的代码可以轻易的被反编译,有些企业会给自己的类做特殊的加密,防止反编译,类加密后就不能再用java的。
classloader去加载类了,这时就需要自定义classloader,再加载类的时候先解密类,然后再加载。
具体的代码自己可以百度一下class加密有很多文章介绍的。