throw new ClassNotFoundException(name);
}
}
LZ截取了主要的部分,为了突出这三个方法。在上面LZ加了简单的注释,相信经过刚才的介绍,各位应该能看出来这是一个模板方法模式,只是它没有定义抽象方法,因为findClass这个方法,并不是必须实现的,所以JDK选择留给程序员们自己选择是否要覆盖。
从代码上我们可以看出,在ClassLoader中定义的算法顺序是。
1,首先看是否有已经加载好的类。
2,如果父类加载器不为空,则首先从父类类加载器加载。
3,如果父类加载器为空,则尝试从启动加载器加载。
4,如果两者都失败,才尝试从findClass方法加载。
这是JDK类加载器的双亲委派模型,即先从父类加载器加载,直到继承体系的顶层,否则才会采用当前的类加载器加载。这样做的目的刚才已经说了,是为了JVM中类的一致性。
如果有读者第一次接触这方面的知识,估计会比较迷茫,下面LZ给出一个例子。各位猜测下下面程序的运行结果会是什么?
[java]
package com.classloader;
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
Class< > clazz = ClassLoader.getSystemClassLoader().loadClass("com.classloader.ClassLoaderTest");
Object entity = clazz.newInstance();
System.out.println(entity instanceof ClassLoaderTest);
}
}
package com.classloader;
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
Class< > clazz = ClassLoader.getSystemClassLoader().loadClass("com.classloader.ClassLoaderTest");
Object entity = clazz.newInstance();
System.out.println(entity instanceof ClassLoaderTest);
}
}
相信各位都可以毫无疑问的猜测出来,结果应该是true,这是因为entity是ClassLoaderTest类的一个实例,instanceof关键字用来判断一个实例是否属于一个特定的类型,所以结果就是true。
那么各位再来猜猜下面这段代码的运行结果会是什么?
[java]
package com.classloader;
import java.io.IOException;
import java.io.InputStream;
class MyClassLoader extends ClassLoader{
public Class< > loadClass(String name) throws ClassNotFoundException {
String fileName = name.substring(name.lastIndexOf(".")+1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if (is == null) {
return super.loadClass(name);
}
try {
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
throw new ClassNotFoundException();
}
}
}
public class ClassLoaderTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ClassLoader classLoader = new MyClassLoader();
Class< > clazz = classLoader.loadClass("com.classloader.ClassLoaderTest");
Object entity = clazz.newInstance();
System.out.println(entity instanceof ClassLoaderTest);
}
}
package com.classloader;
import java.io.IOException;
import java.io.InputStream;
class MyClassLoader extends ClassLoader{
public Class< > loadClass(String name) throws ClassNotFoundException {
String fileName = name.substring(name.lastIndexOf(".")+1) + ".class";
InputStream is = getClass().getResourceAsStream(fileName);
if (is == null) {
return super.loadClass(name);
}
try {
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
throw new ClassNotFoundException();
}
}
}
public class ClassLoaderTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFou