最近在看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產生的,請問這是為什麼。 。 。
第二個程式碼走到
加載
class
文件用getClass().getResourceAsStream