1. 程式人生 > >Java反射機制的理解(Spring學習鋪墊知識點一)

Java反射機制的理解(Spring學習鋪墊知識點一)

由於要學習Spring框架,所以先補充一波對Java反射機制原理的理解。
遇到一個問題或者概念,第一步就是要知道它的基本定義,然後再探尋它是什麼,怎麼用。

什麼是反射?
Java 反射機制是在執行狀態中,對於任意一個類,都能夠獲得這個類的所有屬性和方法,對於任意一個物件都能夠呼叫它的任意一個屬性和方法。這種在執行時動態的獲取資訊以及動態呼叫物件的方法的功能稱為Java 的反射機制。

以上的話通俗一點就是通過這個所謂的反射機制,我能夠在程式執行的時候得到我所需要使用的物件的一切,唯一的條件就是我必須知道這個類的名稱。一旦我知道這個類叫什麼,我就可以向虛擬機器提出我需要這個物件的請求,虛擬機器會自動給你建立物件,而不用你再一個個new出來了。

回想之前的開發,我們若要獲取一個類物件的屬性或者方法,需要使用new一個物件的例項,然後呼叫該物件的方法。但是如果我們使用反射,我們就不需要通過new來獲取方法,而是在執行中動態獲取,從而降低隨著需求的增加而修改原始碼的情況發生(降低耦合)

這兒我使用例子來闡明反射的作用,便於更好的理解。

一般的程式碼會按照如下的格式:

interface Fruit {
    public abstract void eat();
}

class Apple implements Fruit{
    public void eat(){
        System.out.println("eat apple"
); } } class Peach implements Fruit{ public void eat(){ System.out.println("eat peach"); } } class Factory{ public static Fruit getInstance(String fruitname){ Fruit f = null; if ("Apple".equals(fruitname)){ f = new Apple(); } if ("Peach"
.equals(fruitname)){ f = new Peach(); } return f; } } class Main{ public static void main(String[] args) { Fruit f = Factory.getInstance("Peach"); if(f != null){ f.eat(); } } }

我們發現這樣的工廠方法是存在弊端的,比如我現在想要新增一個水果Orange,那開發者必須到Factory類內部進行修改,新增if條件語句重新判斷fruitname是不是Orange。隨著時間的推移,這個Factory類會越來越臃腫,這對於程式碼的更新維護是非常致命的。那麼如果我們想要避免這種問題,就可以嘗試使用反射機制。接下來我將給大家演示反射機制的程式碼怎麼寫的,請各位讀者仔細比較。

interface Fruit {
    public abstract void eat();
}

class Apple implements Fruit{
    public void eat(){
        System.out.println("eat apple");
    }
}

class Peach implements Fruit{
    public void eat(){
        System.out.println("eat Peach");
    }
}

class Factory {
    public static Fruit getInstance(String classname){
        Fruit f = null;
        try{
            f = (Fruit) Class.forName(classname).newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }
        return f;
    }
}

class Main{
    public static void main(String[] args) {
        Fruit f = Factory.getInstance("Peach");
        if(f != null){
            f.eat();
        }
    }
}

通過比較我們可以發現同一個Factory裡的方法接收的是不一樣的引數,不使用反射的則是接收fruitname,而使用反射的則是接收classname,也就是類名。這樣我們只要給出具體類的名字,反射機制就會自動讀取然後幫助你新建一個物件,不再需要使用new自己手動建立新的物件了。

那麼哪裡能體現出解除耦合呢?
我們可以觀察上面的程式碼,如果我們需要新增新的水果子類,通過反射機制,我們不需要對Factory類中的程式碼進行修改,只需要直接新增水果子類然後記住類名即可。而原來的程式碼再新增子類的同時還需要修改Factory程式碼增加判斷條件。看到這兒,反射的基本概念與使用應該就理解了。反射機制還有許多強大的地方,具體操作可以去參考API手冊。

當然,反射也是存在一定的弊端的,雖然給我們程式碼帶來了低耦合,但是使用起來開銷非常大,所以這就告誡我們不要隨意刻意使用反射機制,一定要把它用在最需要的地方。

初步瞭解了反射與工廠模式,我們就有基礎去接觸Spring框架中的IoC(控制反轉)概念,Spring把這兩個技術運用的非常恰當,可見不管多複雜多先進的框架都是從最基本最簡單的概念開始的,技術的核心肯定是最簡單的,這話就算為自己下一步學習Spring打打氣啦: )