Java核心API之反射

一、什麼是Java反射

    Java反射是Java語言自身提供的一種運行機制,主要作用是實現類的動態加載,增加程序的靈活性,實現程序的進一步解耦,舉個例子
class  Office
{
    public static void main(String[] args) 
    {
        //new 創建對象是靜態加載類,在編譯時刻就需要加載所有可能使用到的類
        //通過動態加載類可以解決該問題
        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類,所以無法通過編譯
解決方法是變動態加載爲靜態加載,即使用Java反射機制,具體實現如下:
先說一句幫助大家理解的話:在Java中萬事萬物皆對象,那麼我們自己寫的類也是對象,是Java中Class類的對象

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

        if("Word".equals(args[0]))
        {
            try{
            //調用Class類的forName方法,根據類名獲取反射
            Class c1 = Class.forName("Word");
            //調用Class類的newInstance方法創建對象
            Word w =(Word) c1.newInstance();
            }catch(Exception e){
            e.printStackTrace();
            }
            //Word w = new Word();
            //w.start();
        }
        if("Excel".equals(args[0])){
            //Excel e = new Excel();
            //e.start();
        }
    }
}

運行結果:
這裏寫圖片描述
這樣程序編譯的時候就不會報錯了,因爲現在的對象是在運行階段創建的,只有當你用到某個類的實例對象時該對象纔會被創建。
那麼如何實現程序的的進一步解耦呢,同樣舉例說明:
首先,我們需要創建一個接口類來制定一個人統一的標準

interface OfficeAble
{
    public void start();
}

然後讓Word類和Excel類來實現這個接口
Word類:

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

Excel類:

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

然後是修改後的Office類:

class  OfficeBetter
{
    public static void main(String[] args) 
    {
        try{
            //根據傳入的參數創建該參數的反射(官網稱爲類類型)
            Class c1 = Class.forName(args[0]);

            //上轉型,創建傳入參數類的實例對象
            OfficeAble oa =(OfficeAble)c1.newInstance();
            oa.start();
        }
        catch(Exception e)
            {
            e.printStackTrace();
        }
    }
}

運行結果:
這裏寫圖片描述
通過將類型參數化就實現了等號右邊的解耦,可以根據需要調用的類的不同創建不同類的實例化對象,這樣以後不管你其他的類怎麼改動都不需要再改動此處代碼。

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