我自己定义了一个ClassLoader叫MyClassLoader,它继承了ClassLoader,重写了findClass方法(源码在下面)。MyClassLoader中指定的读取路径是当前classpath(即app的bin目录)。我用MyClassLoader加载自定义的Test2类(该类文件也在app的bin目录下),从获得的实例对象中输出它的classloader,输出的是MyClassLoader,但是依照双亲委托模型,加载该类的不应该是AppClassLoader吗(因为AppClassLoader的职责是从App的classpath下加载类)?怎么会是我自己定义的MyClassLoader呢?请大家帮我解答一下,谢谢。源码如下:
Test.java源码:
public class Test{
static class MyClassLoader extends ClassLoader{
public MyClassLoader(){
super();
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String classPath = MyClassLoader.class.getResource("/").getPath(); //得到classpath
String fileName = name.replace(".", "/") + ".class" ;
File classFile = new File(classPath , fileName);
if(!classFile.exists()){
throw new ClassNotFoundException(classFile.getPath() + " 不存在") ;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
ByteBuffer bf = ByteBuffer.allocate(1024) ;
FileInputStream fis = null ;
FileChannel fc = null ;
try {
fis = new FileInputStream(classFile) ;
fc = fis.getChannel() ;
while(fc.read(bf) > 0){
bf.flip() ;
bos.write(bf.array(),0 , bf.limit()) ;
bf.clear() ;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fis.close() ;
fc.close() ;
} catch (IOException e) {
e.printStackTrace();
}
}
return defineClass(bos.toByteArray() , 0 , bos.toByteArray().length) ;
}
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
MyClassLoader mycl = new MyClassLoader();
Class<?> c = mycl.findClass("Test2");
Object o = c.newInstance();
System.out.println(o.getClass().getClassLoader());
}
}
Test.java源码:
public class Test2 {
public Test2(){
}
}
经过这几天的学习,我好想找到了答案,请大家评判一下:
在classpath目录下的class类文件,AppClassLoader会自动去加载,但是我自己定义的MyClassLoader也可以去加载,这两个过程互不影响。只不过AppClassLoader和MyClassLoader加载后,这个类就在不同命名空间下同时创建了对象,在main方法中执行System.out.println(o instanceof Test2);结果为false,o是由MyClassLoader加载生成的,而Test2是由AppClassLoader加载的,所以结果是false。
mycl.findClass("Test2"); 这里应该调用loadClass方法,
loadClass方法才会依照双亲委托模型定义clas
请问:findClass和loadClass谁符合双亲委派模型?
谢谢大家,我通过看源码明白了。
如果通过自定义的MyClassLoader调用loadClass方法加载类,则按照双亲委托模型机制进行类加载;如果调用findClass方法加载类,则直接通过自定义的类进行类加载。
哪个ClassLoader实例调用的defineClass,就是哪个加载的撒……