基本概念:什麼是 Java 的反射機制

1、JAVA反射機制是在運行狀態中,
 對於任意一個類,都能夠知道這個類的所有屬性和方法;
 對於任意一個對象,都能夠調用它的任意一個方法和屬性;
這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。

2、Java反射機制主要提供了以下功能:
 在運行時判斷任意一個對象所屬的類;
 在運行時構造任意一個類的對象;
 在運行時判斷任意一個類所具有的成員變量和方法;
 在運行時調用任意一個對象的方法;
 生成動態代理。

3、反射技術大量用於Java設計模式和框架技術,最常見的設計模式就是工廠模式單例模式

單例模式(Singleton)

這個模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄 數據庫連接都需要這樣的單線程操作。這樣做就是爲了節省內存空間,保證我們所訪問到的都是同一個對象。
單例模式要求保證唯一,那麼怎麼樣才能保證唯一性呢?對了,這就是靜態變量。單例模式有以下兩種形式:

第一種形式:

package reflect; 
public class Singleton {  
    private Singleton() { 
    }  
    private static Singleton instance = new Singleton(); 
    // 這裏提供了一個供外部訪問本class的靜態方法,可以直接訪問 
    public static Singleton getInstance() { 
           return instance; 
    }    
} 
class SingRun{ 
    public static void main(String[] args){ 
       //這樣的調用不被允許,因爲構造方法是私有的。 
       //Singleton x=new Singleton();      
       //得到一個Singleton類實例 
       Singleton x=Singleton.getInstance();   
       //得到另一個Singleton類實例 
       Singleton y=Singleton.getInstance();     
       //比較x和y的地址,結果爲true。說明兩次獲得的是同一個對象 
       System.out.println(x==y); 
    } 
} 

第二種形式:

public class Singleton { 
    //先申明該類靜態對象 
    private static Singleton instance = null;   
    //創建一個靜態訪問器,獲得該類實例。加上同步,表示防止兩個線程同時進行對象的創建 
    public static synchronized Singleton getInstance() {      
       //如果爲空,則生成一個該類實例 
       if (instance == null){ 
           instance = new Singleton(); 
       } 
       return instance; 
    } 
} 

工廠模式(Factory)

工廠模式是我們最常用的模式了,著名的Jive論壇 ,就大量使用了工廠模式,工廠模式在Java程序系統可以說是隨處可見。
 爲什麼工廠模式是如此常用?是因爲工廠模式利用Java反射機制和Java多態的特性可以讓我們的程序更加具有靈活性。用工廠模式進行大型項目的開發,可以很好的進行項目並行開發。就是一個程序員和另一個程序員可以同時去書寫代碼,而不是一個程序員等到另一個程序員寫完以後再去書寫代碼。其中的粘合劑就是接口和配置文件。之前說利用接口可以將調用和實現相分離。那麼這是怎麼樣去實現的呢?工廠模式可以爲我們解答。
 我們先來回顧一下軟件的生命週期,分析、設計、編碼、調試與測試。其中分析就是指需求分析,就是知道這個軟件要做成什麼樣子,要實現什麼樣的功能。功能知道了,這時就要設計了。設計的時候要考慮到怎麼樣高效的實現這個項目,如果讓一個項目團隊並行開發。這時候,通常先設計接口,把接口給實現接口的程序員和調用接口的程序員,在編碼的時候,兩個程序員可以互不影響的實現相應的功能,最後通過配置文件進行整合。
代碼示例:

interface InterfaceTest{ 
    public void getName();//定義獲得名字的方法 
} 

接口有了,那麼得到這個接口,進行實現編碼的程序員應該怎麼做呢?對了,實現這個接口,重寫其中定義的方法
接口實現方法:

class Test1 implements InterfaceTest{ 
    public void getName() { 
       System.out.println("test1"); 
    } 
} 
class Test2 implements InterfaceTest{ 
    public void getName() { 
       System.out.println("test2"); 
    } 
   
} 

大家可以發現,當接口定義好了以後,不但可以規範代碼,而且可以讓程序員有條不紊的進行功能的實現。實現接口的程序員根本不用去管,這個類要被誰去調用。 那麼怎麼能獲得這些程序員定義的對象呢?在工廠模式裏,單獨定義一個工廠類來實現對象的生產,注意這裏返回的接口對象。
工廠類,生產接口對象:

class Factory{ 
    //創建私有的靜態的Properties對象 
    private static Properties pro=new Properties(); 
    //靜態代碼塊 
    static{ 
       try {        
           //加載配置文件 
           pro.load(new FileInputStream("file.txt")); 
       } catch (Exception e) { 
           e.printStackTrace(); 
       } 
    } 
    private static Factory factory=new Factory(); 
    private Factory(){}   
    public static Factory getFactory(){ 
       return factory; 
    } 
    public  InterfaceTest getInterface(){ 
       InterfaceTest interfaceTest=null;//定義接口對象     
       try { 
           //根據鍵,獲得值,這裏的值是類的全路徑 
           String classInfo=pro.getProperty("test");  
           //利用反射,生成Class對象 
           Class c=Class.forName(classInfo);  
           //獲得該Class對象的實例 
           Object obj=c.newInstance(); 
           //將Object對象強轉爲接口對象 
           interfaceTest=(InterfaceTest)obj; 
       } catch (Exception e) { 
           e.printStackTrace(); 
       } 
       //返回接口對象 
       return interfaceTest; 
    } 
} 

配置文件內容:

test=factory.Test2 

通過這個類,大家可以發現,在調用的時候,得到的是個接口對象。而一個接口變量可以指向實現了這個接口的類對象。在利用反射的時候,我們並沒有直接把類的 全路徑寫出來,而是通過鍵獲得值。這樣的話,就有很大的靈活性,只要改變配置文件裏的內容,就可以改變我們調用的接口實現類,而代碼不需做任何改變。在調 用的時候,我們也是通過接口調用,甚至我們可以連這個接口實現類的名字都不知道。
調用方法:

public class FactoryTest { 
    public static void main(String[] args) { 
       //獲得工廠類的實例 
       Factory factory=Factory.getFactory(); 
       //調用獲得接口對象的方法,獲得接口對象 
       InterfaceTest inter=factory.getInterface(); 
       //調用接口定義的方法 
       inter.getName(); 
    } 
} 

上面的代碼就是調用方法。大家可以發現,在調用的時候,我們根本沒有管這個接口定義的方法要怎麼樣去實現它,我們只知道這個接口定義這個方法起什麼作用就行了。上面代碼運行結果要根據配置文件來定。如果配置文件裏的內容是test=factory.Test2。那麼表示調用factory.Test2這個 類裏實現接口的方法,這時候打印“test2”。如果配置文件裏的內容是test=factory.Test1。那麼表示調用factory.Test1 這個類裏實現接口的方法,這時候打印“test1”。

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