最近在看Java虚拟机,类加载器那节举了这么一个例子:
/**
*类加载器与instanceof关键字演示
**
@author zzm
*/
public class ClassLoaderTest{
public static void main(String[]args) throws Exception{
ClassLoader myLoader=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){
throw new ClassNotFoundException(name);
}
}
}
;
Object obj=myLoader.loadClass("org.fenixsoft.classloading.ClassLoaderTest").newInstance();
System.out.println(obj.getClass());
System.out.println(obj instanceof org.fenixsoft.classloading.ClassLoaderTest);//false
}
}
总而言之就是用自定义的类加载器去加载一个类,返回的类与jvm自带的SystemClassLoader加载的类不同。
那么如果用一个继承自ClasserLoader的类,按理说也是同样的效果
package jvm;
public class MyClassLoader extends ClassLoader{
@Override
public Class<?> loadClass(String fullClassName) throws ClassNotFoundException{
try {
String fileName = fullClassName.substring(fullClassName.lastIndexOf(".")+1,fullClassName.length())+".class";
InputStream is = getResourceAsStream(fileName);
if(is==null){
return super.loadClass(fullClassName);
}
byte[] bytes = new byte[is.available()];
is.read(bytes);
return defineClass(fullClassName,bytes,0,bytes.length);
}catch (Exception e){
throw new ClassNotFoundException();
}
}
public static void main(String[] args) throws Exception{
ClassLoader myClassLoader = new MyClassLoader();
/**
ClassLoader myClassLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String fullClassName) throws ClassNotFoundException {
try {
String fileName = fullClassName.substring(fullClassName.lastIndexOf(".")+1,fullClassName.length())+".class";
InputStream is = getClass().getResourceAsStream(fileName);
if(is==null){
return super.loadClass(fullClassName);
}
byte[] bytes = new byte[is.available()];
is.read(bytes);
return defineClass(fullClassName,bytes,0,bytes.length);
}catch (Exception e){
throw new ClassNotFoundException();
}
}
};
/**/
ClassLoader systemClassLoader = java.lang.ClassLoader.getSystemClassLoader();
Class myClass = myClassLoader.loadClass("jvm.MyClassLoader");
Class systemClass = systemClassLoader.loadClass("jvm.MyClassLoader");
Object myObj = myClass.newInstance();
Object systemObj = systemClass.newInstance();
System.out.println(myClass.equals(systemClass));//true
System.out.println(myObj.getClass().equals(systemObj.getClass()));//true
}
}
注释里的代码就是匿名内部类的继承,注意到这里myClass和systemClass是完全相等的,但是myClass是使用继承自ClassLoader的类MyClassLoader生成的,请问这是为什么呢。。。
巴扎黑2017-05-17 10:09:45
第二个代码走到
if(is==null){
return super.loadClass(fullClassName);
}
加载class
文件用getClass().getResourceAsStream