最近在看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