1. 程式人生 > >Java反射之——Java動態載入類

Java反射之——Java動態載入類

1、靜態載入和動態載入的區分:

我們在理解動態載入的同時,需要區分Java的編譯和執行:

編譯時載入屬於靜態載入,我們平時開發中使用最多的就是靜態載入,new物件都屬於靜態載入類,在編譯時載入所有可能使用到的類(雖然有可能用不到)。A a = new A();

執行時載入屬於動態載入,我們在表示Class的例項物件的時候使用到的第三種方式,即 class.forName(),在編譯時不會報任何錯誤,只有在使用類並且該類不存在時,才會報ClassNotFoundException 的異常。然後可以通過類的類型別建立該類的物件,即:A a = (A)class.forName("test.A").newInstance();

2、為什麼要使用動態載入類?

在平時開發中,一些開發工具是我們是分不清編譯和執行的,因為開發工具已經幫我們做了,我們可以在一些編輯器中來編寫案例來區分編譯和執行。

靜態載入類——編譯時載入

class Office
{
    public static void main(String[] args) 
    {
        if("word".equals(args[0])){
            Word w = new Word();
            w.start();
        }
        if("Excel".equals(args[0])){
            Excel e = new Excel();
            e.start();
        }
    }
}

因為new物件是靜態載入類,在編譯時就會載入Word類和Excel類,但是Word類和Excel類是不存在的,所以Office類是編譯不成功的,即使Word類存在,Excel類不存在,Office類也是編譯不成功的,所以我們在平時開發中假設有10個功能,如果有1個功能用不了,其餘9個功能也不能使用,這就是編譯時載入導致的。

動態載入類——執行時載入

class OfficeNew
{
    public static void main(String[] args) 
    {
        try{

            //動態載入類,通過類型別建立該類的物件。
            Class c = Class.forName(args[0]);
            OfficeBetter of = (OfficeBetter)c.newInstance();
            of.start();
        }catch(Exception e){
            e.printStackTrace();
        }
        
    }
}

OfficeBetter我們可以看做是使用標準,使用的每一個功能都來實現這個標準。

interface OfficeBetter
{
    public void start();    
}

然後Word類和Excel類共同實現OfficeBetter標準:

class Word implements OfficeBetter 
{
    public void start(){
        System.out.println("word....start");
    }
}

class Excel implements OfficeBetter
{
    public void start() 
    {
        System.out.println("excel....start");
    }
}

如果需要迭代新的功能,我們不需要更改使用類OfficeNew,只需要新增新的的功能並且實現OfficeBetter標準即可,這就是動態載入類給我們帶來的好處。

補充: 

java中class.forNameclassLoader都可用來對類進行動態載入。前者除了將類的.class檔案載入到jvm中之外,還會對類進行解釋,執行類中的static塊。而classLoader只是將.class檔案載入到jvm中,不會執行static中的內容,只有在newInstance才會去執行static塊。Class.forName(name, initialize, loader)帶參函式也可控制是否載入static塊(initialize為true是表示進行初始化,initialize為false表示不需要進行初始化)。並且只有呼叫了newInstance()方法才會呼叫建構函式,建立類的物件 。