对于这个问题一直有疑惑!
PS.顺便吐嘈一句,在SEGMENTFAULT上已经很长时间没有得到满意答案了
首先,大家都知道JVM的类加载器是是双亲委派模型的,但是如果我们写这么一个类:
public class jvm_77{
public static void main(String[] args) throws Exception{
ClassLoader myLoader = new ClassLoader(){
public Class<?> loadClass(String name) throws ClassNotFoundException{
try
{
String fileName = name.substring(name.lastIndexOf(".")+1)+".class";
InputStream is = getClass().getResourceAsStream(fileName);
if(is == null)
{
return super.loadClass(name);//由父类加载
}
byte[] b = new byte[is.available()];
is.read(b);
return defineClass(name,b,0,b.length);
}catch(IOException e)
{
throw new ClassNotFoundException(name);
}
}
};
Object obj = myLoader.loadClass("Chapter7_ClassLoader.jvm_77").newInstance();
jvm_77 obj2 = new jvm_77();
System.out.println(obj.getClass().getClassLoader()); //Chapter7_ClassLoader.jvm_77$1@1888759
System.out.println(obj2.getClass().getClassLoader()); //sun.misc.Launcher$AppClassLoader@45a877
System.out.println(obj.equals(obj2));//false
System.out.println(obj instanceof Chapter7_ClassLoader.jvm_77);//false
System.out.println(obj2 instanceof Chapter7_ClassLoader.jvm_77);//true
}
}
从上面输出结果可以看到obj,obj2的类加载器不同;
问题:
1.此处的MyClassLoader应该就是【开发人员编写的类加载器】吧,那么其基类ClassLoader是【系统类加载器】?
2.为什么obj,obj2的类加载器会不同呢,基于双亲委派模型的话应该会由同一个类加载吧 ? 难道这么容易打破了双亲委派模型?那热加载技术岂不是很容易实现?
1.是的
2.你还没有搞明白什么是双亲加载,当你MyClassLoader来加载制定类时候,首先会从父类中查找是否已经加载过了,若是已经加载过了,那么直接使用,若是没有,继续往上层走。若是到最上层还是没有加载过,那么最上层开始尝试去加载,若是加载成功,直接返回,若是加载失败的话,那么子类去加载,一直到某个子类加载到对象。