黑馬程序員_java基礎加強5

---------------------- android培訓java培訓、期待與您交流! ----------------------




8.類的加載、連接、初始化:

加載:將.class文件讀入到內存,併爲之創建一個java.lang.Class對象。一旦某個類被載入JVM中,同一個類就不會再被載入。在JAVA中,一個類用其全限定類名作爲標識,這裏指的全限定類名包括包名和類名。但在JVM中一個類用其全限定類名和一個加載類ClassLoader的實例ID作爲唯一標識(命名空間)。如:包pg下的Person類MyClassLoader的實例a加載,在JVM中表示爲(Person、pg、a)。

連接:把已讀入虛擬機的二進制Java類數據合併到虛擬機的運行時狀態中去。

      分爲三步:.驗證:加成被夾在的類是否有正確的內部結構,並和其他類協調一致。.  

                準備.:爲類的靜態屬性分配內存,並設置默認初始值。

                解析:將類的二進制數據中的符號引用替換成直接引用。

初始化:主要是對靜態屬性進行初始化,包括兩種方式:聲明靜態屬性時指定初始值、使用    

        靜態代碼塊初始化靜態屬性。

初始化時機:創建類的實例、調用某個類的靜態方法、調用某個類的靜態屬性或爲靜態屬性賦值、用Class.forName("類名")的方式加載類、初始化某個類的子類。通過類名.class方式加載某個類時,不會靜態初始化。

9.Java虛擬機中可以安裝多個類加載器,系統默認三個主要類加載器,每個類負責加載特定位置的類:BootStrap,ExtClassLoader,AppClassLoader。類加載器也是Java類,因爲其他是java類的類加載器本身也要被類加載器加載,顯然必須有第一個類加載器不是不是java類,這正是BootStrap。得到類加載器示例:

ClassLoader loader = ClassLoaderTest.class.getClassLoader();

//打印出當前的類加載器,及該類裝載器的各級父類加載器

while(loader != null){

System.out.println(loader.getClass().getName());

loader = loader.getParent();

}

19.類加載器之間的父子關係和管轄範圍圖

10.類加載器的委託機制:

Java虛擬機要加載一個類時,到底派出哪個類加載器去加載呢?

     首先當前線程的類加載器去加載線程中的第一個類。

     如果類A中引用了類BJava虛擬機將使用加載類A的類裝載器來加載類B。 

     還可以直接調用ClassLoader.loadClass(String name)方法(name字符串沒有.class後綴)來   

     指定某個類加載器去加載某個類。

每個類加載器加載類時,又先委託給其上級類加載器。

當所有祖宗類加載器沒有加載到類,回到發起者類加載器,還加載不了,則拋 

ClassNotFoundException,不是再去找發起者類加載器的兒子,因爲沒有getChild方法, 

即使有,那有多個兒子,找哪一個呢?

每個ClassLoader本身只能分別加載特定位置和目錄中的類,但它們可以委託其他的類裝載器去加載類,這就是類加載器的委託模式。類裝載器一級級委託到BootStrap類加載器,當BootStrap無法加載當前所要加載的類時,然後才一級級回退到子孫類裝載器去進行真正的加載。當回退到最初的類裝載器時,如果它自己也不能完成類的裝載,那就應報告ClassNotFoundException異常。

11.自定義類加載器加載類:

被加載類:

package myclassloadertest;//結合(1)想想此處爲什麼要繼承

public class BeLoadedClass extends MyClassLoaderTest{}

類加載器:

package myclassloadertest;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

    String classDir;

    public MyClassLoader(String classDir) {

this.classDir=classDir;

}

@SuppressWarnings("deprecation")

@Override

    protected Class<?> findClass(String className) {

     String classPath=classDir+"\\"+className+".class";

     ByteArrayOutputStream bao=null;

        InputStream fis=null;

     try {

 fis=new FileInputStream(classPath);

 bao=new ByteArrayOutputStream();

 int hasRead=-1;

 while((hasRead=fis.read())!=-1){

 bao.write(hasRead);

 bao.flush();

 }

 fis.close();

 bao.close();

catch (Exception e) {

e.printStackTrace();

}

byte buffer[]=bao.toByteArray();

     return this.defineClass( buffer, 0, buffer.length);

    }

}

類加載器測試:

package myclassloadertest;

public class MyClassLoaderTest {

public static void main(String[] args) throws Exception {

Class<?> myLoader=new 

                       MyClassLoader("bin\\myclassloadertest").

                       loadClass("BeLoadedClass");

MyClassLoaderTest clazz=(MyClassLoaderTest) //(1)

                        myLoader.newInstance();

System.out.println(clazz.getClass().getClassLoader()

                        .getClass().getName());

}

}

輸出:myclassloadertest.MyClassLoader


---------------------- android培訓java培訓、期待與您交流! ----------------------

詳細請查看:http://edu.csdn.net/heima

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章