ClassLoader类加载器在Java世界中很重要的概念。比如ClassPathResource里就用到了,所以现在系统地说明一下,下面给出个例子程序
public class ClassLoaderDemo {
public static void main(String[] args) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器是" + cl);
//获取委托的父类加载器是
cl = cl.getParent();
System.out.println("委托的父类加载器是" + cl);
Class c = Class.forName("java.lang.Object");
cl = c.getClassLoader();
System.out.println("Object类的加载器 = " + cl);
c = Class.forName("arthur.java.fromInternet.ClassLoaderDemo");
cl = c.getClassLoader();
System.out.println("本类的加载器是" + cl);
}
}
运行结果如下: 系统类加载器是 sun.misc.Launcher$AppClassLoader@19821f 委托的父类加载器是sun.misc.Launcher$ExtClassLoader@addbf1 Object类的加载器null 本类的加载器是sun.misc.Launcher$AppClassLoader@19821f 类加载器可以分为三种,一类是启动类加载器(Bootstrap ClassLoader),一类是扩展类加载器(Extension ClassLoader),这个加载器由sun.misc.Launcher$ExtClassLoader来实现,上面的委托的父类加载器就是这个类型,还有一类是应用程序加载器,sun.misc.Launcher$AppClassLoader类实现,可以对照上面的运行结果看看各自属于哪个加载器。 三个加载器的关系可以如下表示:启动类加载器 defineClass(String name,byte[] b, int off,int len),注意字节数组是由组成类数据的字节组成,所以我们可以以下列方式实现自己的类加载器(摘自深入理解java虚拟机)
public class MyCLassLoader {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoader myCL = new ClassLoader() {
@Override
public Class loadClass(String pathName) throws ClassNotFoundException {
String fileName = pathName.substring(pathName.lastIndexOf(".") + 1) + ".class";
byte b[] = null;
try {
InputStream is = this.getClass().getResourceAsStream(fileName);
if(is == null){
return super.loadClass(pathName);
}
b = new byte[is.available()];
is.read(b);
} catch (IOException ex) {
ex.printStackTrace();
}
return this.defineClass(pathName, b, 0, b.length);
}
};
Class c = myCL.loadClass("arthur.java.fromInternet.MyCLassLoader");
System.out.println(c);
Object mcl = c.newInstance();
System.out.println(mcl);
}
}