深入java虛擬機器學習–類的載入機制(四)
類載入的名稱空間
每個類載入器都有自己的名稱空間,名稱空間由所有以此載入器為初始類載入器的類組成,不同名稱空間的兩個類是不可見的,但只要得到類所對應的Class物件的refrence(反射),還是可以訪問另一個名稱空間的類資訊的。
同一個名稱空間內的類是相互可見的,子載入器的名稱空間包含所有父載入器的名稱空間,也就是說由子載入器載入的類能看到父載入器載入的類。例如:系統類載入器載入的類能看到根類載入器載入的類(使用者自定的類可以訪問java.lang.*包下的資訊),由父載入器載入的類不能看到子載入器載入的類。
如果兩個載入器之間沒有直接或者間接的父子關係,那麼它們個字載入的類相互不可見。
建立使用者自定義的類載入器
要建立使用者自定義的類載入器,只需要擴充套件java.lang.ClassLoader類,然後覆蓋它的findClass(String name)方法即可,該方法根據引數指定的類的名字,返回對應的Class物件的引用。
protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); }
我們可以按到ClassLoader裡面的findClass方法的預設實現會丟擲ClassNotFoundException異常,我們只需要在自定義的載入器裡面重寫,即可。
public class MyClassLoader extends ClassLoader { private String name;//類載入器的名字 private String path="";//載入類的預設路徑 private String fileType=".class"; //class檔案的副檔名 public MyClassLoader(String name){ super();//讓系統類載入器成為該類載入器的父載入器 this.name=name; } public MyClassLoader(ClassLoader parent,String name){ super(parent);//顯示指定該類載入器的父載入器 this.name=name; } @Override public String toString() { return this.name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } /** * 抽象類ClassLoader的findClass函式預設是丟擲異常的。而前面我們知道, * loadClass在父載入器無法載入類的時候,就會呼叫我們自定義的類載入器中的findeClass函式, * 因此我們必須要在loadClass這個函式裡面實現將一個指定類名稱轉換為Class物件. * @param name * @return */ @Override protected Class<?> findClass(String name) { byte [] data=this.loadClassData(name); return this.defineClass(name,data,0,data.length); } private byte[] loadClassData(String name) { InputStream is=null; byte [] data=null; ByteArrayOutputStream baos=null; try { this.name=this.name.replace(".","\"); is=new FileInputStream(new File(path+name+fileType)); baos=new ByteArrayOutputStream(); int ch=0; while(-1!=(ch=is.read())){ baos.write(ch); } data= baos.toByteArray(); } catch(Exception e){ e.printStackTrace(); } finally { try { is.close(); baos.close(); } catch(IOException e) { e.printStackTrace(); } } return data; } public static void main(String[] args) throws Exception { MyClassLoader loader1 = new MyClassLoader("loader1");//沒有指定loader的父載入器,則預設的父載入器為系統類載入器 loader1.setPath("G:\myapp\loader1\"); MyClassLoader loader2 = new MyClassLoader(loader1,"loader2");//指定loader2的父載入器為loader1,這裡的loader1和loader2都為MyClassLoader的例項 loader2.setPath("G:\myapp\loader2\"); MyClassLoader loader3 = new MyClassLoader(null,"loader3");//bootstrap類載入器 loader3.setPath("G:\myapp\loader3\"); //test(loader1); test(loader2); test(loader3); } public static void test(ClassLoader loader) throws Exception { Class clazz=loader.loadClass("Sample"); Object object=clazz.newInstance(); }
開開心心編碼,快快樂樂生活。
相關文章
- Java 虛擬機器之四:Java類載入機制Java虛擬機
- 深入理解Java虛擬機器 --- 類載入機制Java虛擬機
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- JVM學習-虛擬機器類載入機制JVM虛擬機
- java虛擬機器類載入機制Java虛擬機
- Java 虛擬機器類載入機制Java虛擬機
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- Java虛擬機器(六):類載入機制Java虛擬機
- 深入理解JVM,虛擬機器類載入機制JVM虛擬機
- 虛擬機器類載入機制虛擬機
- JVM(三)-java虛擬機器類載入機制JVMJava虛擬機
- 虛擬機器類載入機制:類載入時機虛擬機
- 【Java虛擬機器規範】JVM類載入機制Java虛擬機JVM
- 虛擬機器類載入機制_類載入的過程虛擬機
- 【進階之路】深入理解Java虛擬機器的類載入機制(長文)Java虛擬機
- 《深入理解java虛擬機器》第七章讀書筆記——虛擬機器類載入機制Java虛擬機筆記
- 虛擬機器系列 | JVM類載入機制虛擬機JVM
- JVM(五)----虛擬機器類載入機制JVM虛擬機
- JVM(7)-虛擬機器類載入機制JVM虛擬機
- 深入淺出JVM(三)之HotSpot虛擬機器類載入機制JVMHotSpot虛擬機
- 深入理解jvm-2Edition-虛擬機器類載入機制JVM虛擬機
- 深入理解JVM虛擬機器6:深入理解JVM類載入機制JVM虛擬機
- 虛擬機器類載入機制_類載入時機和類的生命週期虛擬機
- 深入理解JVM(③)虛擬機器的類載入時機JVM虛擬機
- 深入學習Java虛擬機器——類檔案結構Java虛擬機
- (深入理解 Java虛擬機器)一篇文章帶你深入瞭解Java 虛擬機器類載入器Java虛擬機
- 深入學習Java虛擬機器——虛擬機器位元組碼執行引擎Java虛擬機
- 面試官,不要再問我“Java虛擬機器類載入機制”了面試Java虛擬機
- 深入理解JVM(③)虛擬機器的類載入過程JVM虛擬機
- 深入理解JVM——(四)類載入機制JVM
- 是時候瞭解一波虛擬機器的類載入機制虛擬機
- 深入理解JVM(③)虛擬機器的類載入器(雙親委派模型)JVM虛擬機模型
- java類載入機制Java
- Java基礎-類載入器以及載入機制Java
- JVM學習(三)——類載入機制JVM
- 深入理解java虛擬機器Java虛擬機
- JAVA虛擬機器學習筆記Java虛擬機機器學習筆記