首先先上代码:
package com.tanghailin.classloading.demo08;
import java.io.IOException;
import java.io.InputStream;
/**
* 自定义加载器:
* loadClass:加载类
* findClass:找这个类,是否已经被加载过
* defineClass:把字符数组转为class对象
* 对于任意一个类,都需要由加载它的类加载器和类本身来决定唯一性
* 即使是同一个类,同一个虚拟机,但不同的类加载器,这样子的类也不是同一个
* @author aaron
*
*/
public class ClassLoaderTest {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ClassLoader classLoader = new ClassLoader() {
@Override
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) {
// TODO Auto-generated catch block
throw new ClassNotFoundException(name);
}
}
};
//加载本包(demo08包)类的时候:即加载ClassLoaderTest时,输出为
/**class com.tanghailin.classloading.demo08.ClassLoaderTest
* false
*/
//加载非本包(非demo08包)类的时候:即加载TestClass2时,输出为
/**class com.tanghailin.classloading.demo07.TestClass2
* true
*/
// Object obj = classLoader.loadClass("com.tanghailin.classloading.demo08.ClassLoaderTest").newInstance();
Object obj = classLoader.loadClass("com.tanghailin.classloading.demo07.TestClass2").newInstance();
System.out.println(obj.getClass());
// System.out.println(obj instanceof com.tanghailin.classloading.demo08.ClassLoaderTest);//false
System.out.println(obj instanceof com.tanghailin.classloading.demo07.TestClass2);//true
}
}
问题:类的全限定名不同会导致使用的类加载器不一样??
首先,上述的ClassLoaderTest是在demo08包下的类,如果我用demo08包下的类来测试,在instanceof比较时,会返回false;这是因为obj是用自定义类加载器加载的;而ClassLoaderTest是用应用程序类加载器加载的。
但是问题来了,如果我用demo07包(总之,是非demo08包)下的类来测试,在instanceof比较时,会返回true。这时问题就出现了。。。
经过排查,两种情况下,加载的时候,都会进入重写的loadClass方法下,但是在测试demo07包的时候,发现会在应用程序类加载器中加载,而不是在自定义类加载器中加载。这又是为什么???
哪位大佬可以给点思路或意见???
有想法的小伙伴,在评论留下你的见解!!!望赐教
网友评论