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打打氣啦: )