java中Class與Object及反射機制

轉:http://blog.csdn.net/xingcaizxc/article/details/8786744 

平時看代碼時,總是碰到這些即熟悉又陌生的名次,每天都與他們相見,但見面後又似曾沒有任何的交集,所以今天我就來認識下這兩個江湖俠客的背景:

CLASS

    在Java中,每個class都有一個相應的Class對象。也就是說,當我們編寫一個類,編譯完成後,在生成的.class文件中,就會產生一個Class對象,用於表示這個類的類型信息
獲取Class實例的三種方式:
    (1)利用對象調用getClass()方法獲取該對象的Class實例;
    (2)使用Class類的靜態方法forName(),用類的名字獲取一個Class實例(staticClass forName(String className) Returns the Classobject associated with the class or interface with the given stringname. );
    (3)運用.class的方式來獲取Class實例,對於基本數據類型的封裝類,還可以採用.TYPE來獲取相對應的基本數據類型的Class實例
    在newInstance()調用類中缺省的構造方法 ObjectnewInstance()(可在不知該類的名字的時候,常見這個類的實例) Creates a new instance of the class represented by this Classobject.
    在運行期間,如果我們要產生某個類的對象,Java虛擬機(JVM)會檢查該類型的Class對象是否已被加載。如果沒有被加載,JVM會根據類的名稱找到.class文件並加載它。一旦某個類型的Class對象已被加載到內存,就可以用它來產生該類型的所有對象

    Class對象的生成方式如下:

    1.Class.forName("類名字符串") (注意:類名字符串必須是全稱,包名+類名);
    2.類名.class;
    3.實例對象.getClass();

[html] view plaincopy
  1. package baseJava;  
  2.   
  3. public class TestClass {  
  4.   
  5.     /**  
  6.      * @param args  
  7.      * 2013-4-11 上午10:30:05  
  8.      * @author zhao_xingcai  
  9.      */  
  10.     public static void main(String[] args) {  
  11.         // TODO Auto-generated method stub  
  12.         try {  
  13.           
  14.             //測試Class.forName()    
  15.             Class classForName = Class.forName("baseJava.TestClass");  
  16.             System.out.println("classForName  : [" + classForName + "]");  
  17.               
  18.             //測試類名.class  
  19.             Class classForName2 = TestClass.class;  
  20.             System.out.println("classForName2 : [" + classForName2 + "]");  
  21.               
  22.             //測試Object.getClass()   
  23.             TestClass newInstance = new TestClass();  
  24.             System.out.println("newInstance   : [" + newInstance.getClass() + "]");  
  25.               
  26.             //hashCode指的是內存的地址  
  27.             System.out.println("newInstanceHashCode   : [" + newInstance.hashCode() + "]");  
  28.               
  29.             //toString代表該對象的一個字符串  
  30.             //格式:this.getClass().getName() + '@' + Integer.toHexString(hashCode())  
  31.             System.out.println("newInstanceToString   : [" + newInstance.toString() + "]");  
  32.               
  33.               
  34.         }catch (ClassNotFoundException e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.     }  
  38.     /*  
  39.      * 構造函數  
  40.      */  
  41.     public TestClass() {  
  42.         System.out.println(" 構造函數");  
  43.     }  
  44.       
  45.     /*  
  46.      * 靜態的參數初始化    
  47.      */  
  48.     static {  
  49.         System.out.println("靜態的參數初始化  ");  
  50.     }  
  51.       
  52.     /*  
  53.      * 非靜態的參數初始化    
  54.      */  
  55.     {  
  56.         System.out.println("非靜態的參數初始化  ");  
  57.     }  
  58.   
  59. }  



運行結果如下:

靜態的參數初始化  
classForName  : [class baseJava.TestClass]
classForName2 : [class baseJava.TestClass]
非靜態的參數初始化  
 構造函數
newInstance   : [class baseJava.TestClass]
newInstanceHashCode   : [12677476]
newInstanceToString   : [baseJava.TestClass@c17164]

    也就是說:

    三種方法生成CLASS對象是一樣的,因爲CLASS在JVM的名稱是一樣的,但是三種生成的方法略有不同:靜態的方法屬性初始化,是在加載類的時候初始化。而非靜態方法屬性初始化,是new類實例對象的時候加載。當我們編寫一個新的JAVA類時,JVM就會幫我們編譯成CLASS對象,存放在同名的.class文件中,在運行時,當需要生成這個類的對象時,JVM就會檢查此類是否裝載到內存中,會沒有裝載,就把.class裝載到內存中,若裝載過,則根據.class生成對象。

OBJECT對象

    在Java中有這樣一個類,它是所有類的祖先,任何類都是其子孫類,它就是java.lang.Object,如果一個類沒有顯式地指明其父類,那麼它的父類就是Object。如同我們稱自己爲炎黃子孫一樣,所有的類都可以稱爲Object子孫,^_^。在java中除了基本型別(數字、字符、布爾值,primitive type)不是對象之外,其它的均爲對象(class type)。那麼,這個Object到底給我們留下了什麼“遺產”呢?下面將從最基本的講起:

    1.  public boolean equals(Object obj).

    所有的類均可以按照自己的需要對equals方法進行覆蓋,顧名思義,這個方法可用來比較兩個對象是否“相等”,至於什麼才叫“相等”,各個類可以根據自己的情況與需要自行定義。例如String,就是要求兩個對象所代表的字符串值相等,而對於一個僱員類(Employee),則可能是要求姓名、年齡、工資等一樣纔算是“相等”。儘管不同的類有不同的規則,但是有一條規則卻是公用的,它就是:如果兩個對象是“一樣”(identical)的,那麼它們必然是“相等”(equals)的。那麼什麼才叫“一樣”?如果a==b,我們就說a和b是“一樣的”,即a和b指向(refer to)同一個對象。Object類中的equals方法實施的就是這一條比較原則,對任意非空的指引值a和b,當且僅當a和b指向同一個對象時才返回true。

    2.  public int hashCode()

    每個類都可以複寫Object類中的hashCode方法,Object類中的hashCode方法就是簡單

地將對象在內存中的地址轉換成int返回。這樣,如果一個類沒有複寫hashCode方法,那麼它的hashCode方法就是簡單地返回對象在內存中的地址。在JDK中,對hashCode也定義了一系列約束,其中有一條就是如果兩個對象是“equal”的,那麼它們的hashCode方法返回的整數值必須相同,但是如果兩個對象是“unequal”,那麼hashCode方法的返回值不一定必須不同。正因爲這個約束,我們如果複寫了equals()方法,一般也要複寫hashCode方法。
    3.public String toString()

    toString方法是一個從字面上就容易理解的方法,它的功能是得到一個能夠代表該對象的一個字符串,Object類中的toString方法就是得到這樣的一個字符串:this.getClass().getName() + '@' + Integer.toHexString(hashCode()),各個類可以根據自己的實際情況對其進行改寫。

 

JAVA的反射機制

    JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
    Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。

[html] view plaincopy
  1. package baseJava;  
  2.   
  3. import java.lang.reflect.Array;  
  4. import java.lang.reflect.Constructor;  
  5. import java.lang.reflect.Field;  
  6. import java.lang.reflect.Method;  
  7.   
  8. public class Reflect {  
  9.   
  10.     /**  
  11.      * @param args  
  12.      *            2013-4-11 上午11:20:59  
  13.      * @author zhao_xingcai  
  14.      */  
  15.     public static void main(String[] args) {  
  16.         // TODO Auto-generated method stub  
  17.           
  18.   
  19.     }  
  20.       
  21.     /**  
  22.      * 得到某個對象的屬性  
  23.      * @param owner  
  24.      * @param fieldName  
  25.      * @return  
  26.      * @throws Exception  
  27.      * 2013-4-11 上午11:25:48  
  28.      * @author zhao_xingcai  
  29.      */  
  30.     @SuppressWarnings("unchecked")  
  31.     public Object getProperty(Object owner, String fieldName) throws Exception {  
  32.         //得到該對象的Class  
  33.         Class ownerClass = owner.getClass();  
  34.         //通過Class得到類聲明的屬性  
  35.         Field field = ownerClass.getField(fieldName);  
  36.         //通過對象得到該屬性的實例,如果這個屬性是非公有的,這裏會報IllegalAccessException。  
  37.         Object property = field.get(owner);  
  38.         return property;  
  39.     }  
  40.       
  41.     /**  
  42.      * 獲得某個類的靜態屬性  
  43.      * @param className  
  44.      * @param fieldName  
  45.      * @return  
  46.      * @throws Exception  
  47.      * 2013-4-11 上午11:35:10  
  48.      * @author zhao_xingcai  
  49.      */  
  50.     @SuppressWarnings("unchecked")  
  51.     public Object getStaticProperty(String className, String fieldName)  
  52.             throws Exception {  
  53.         //首先得到這個類的Class  
  54.         Class ownerClass = Class.forName(className);  
  55.         //通過Class得到類聲明的屬性  
  56.         Field field = ownerClass.getField(fieldName);  
  57.         //靜態屬性,直接從類的Class裏取  
  58.         Object property = field.get(ownerClass);  
  59.         return property;  
  60.     }  
  61.       
  62.     /**  
  63.      * 獲取某個對象的方法  
  64.      * @param owner  
  65.      * @param methodName  
  66.      * @param args  
  67.      * @return  
  68.      * @throws Exception  
  69.      * 2013-4-11 上午11:39:05  
  70.      * @author zhao_xingcai  
  71.      */  
  72.     @SuppressWarnings("unchecked")  
  73.     public Object invokeMethod(Object owner, String methodName, Object[] args)  
  74.             throws Exception {  
  75.         //或得這個類的Class  
  76.         Class ownerClass = owner.getClass();  
  77.         //配置參數的Class數組,作爲尋找Method的條件  
  78.         Class[] argsClass = new Class[args.length];  
  79.         for (int i = 0j = args.length; i < j; i++) {  
  80.             argsClass[i] = args[i].getClass();  
  81.         }  
  82.         //通過Method名和參數的Class數組得到要執行的Method  
  83.         Method method = ownerClass.getMethod(methodName, argsClass);  
  84.         //執行該Method,invoke方法的參數是執行這個方法的對象,和參數數組。返回值是Object,也既是該方法的返回值  
  85.         return method.invoke(owner, args);  
  86.     }  
  87.       
  88.     /**  
  89.      * 執行某個類的靜態方法  
  90.      * @param className  
  91.      * @param methodName  
  92.      * @param args  
  93.      * @return  
  94.      * @throws Exception  
  95.      * 2013-4-11 上午11:40:31  
  96.      * @author zhao_xingcai  
  97.      */  
  98.     @SuppressWarnings("unchecked")  
  99.     public Object invokeStaticMethod(String className, String methodName,  
  100.             Object[] args) throws Exception {  
  101.         //獲取該類的class  
  102.         Class ownerClass = Class.forName(className);  
  103.         Class[] argsClass = new Class[args.length];  
  104.             for (int i = 0j = args.length; i < j; i++) {  
  105.         }  
  106.         Method method = ownerClass.getMethod(methodName, argsClass);  
  107.         //invoke的一個參數是null,因爲這是靜態方法,不需要藉助實例運行  
  108.         return method.invoke(null, args);  
  109.     }  
  110.       
  111.     /**  
  112.      * 新建實例,執行帶參數的構造函數來新建實例的方法。  
  113.      * 如果不需要參數,可以直接使用newoneClass.newInstance()來實現。  
  114.      * @param className  
  115.      * @param args  
  116.      * @return  
  117.      * @throws Exception  
  118.      * 2013-4-11 上午11:41:27  
  119.      * @author zhao_xingcai  
  120.      */  
  121.     @SuppressWarnings("unchecked")  
  122.     public Object newInstance(String className, Object[] args) throws Exception {  
  123.         //得到要構造的實例的Class  
  124.         Class newoneClass = Class.forName(className);  
  125.         //得到參數的Class數組  
  126.         Class[] argsClass = new Class[args.length];  
  127.             for (int i = 0j = args.length; i < j; i++) {  
  128.         }  
  129.         //得到構造函數   
  130.         Constructor cons = newoneClass.getConstructor(argsClass);  
  131.         //新建實例  
  132.         return cons.newInstance(args);  
  133.     }  
  134.       
  135.     /**  
  136.      * 判斷是否爲某個類的實例  
  137.      * @param obj  
  138.      * @param cls  
  139.      * @return  
  140.      * 2013-4-11 上午11:42:59  
  141.      * @author zhao_xingcai  
  142.      */  
  143.      @SuppressWarnings("unchecked")  
  144.     public boolean isInstance(Object obj, Class cls) {  
  145.         return cls.isInstance(obj);  
  146.     }  
  147.        
  148.      /**  
  149.       * 得到數組中的某個元素  
  150.       * @param array  
  151.       * @param index  
  152.       * @return  
  153.       * 2013-4-11 上午11:43:33  
  154.       * @author zhao_xingcai  
  155.       */  
  156.      public Object getByArray(Object array, int index) {  
  157.         return Array.get(array, index);  
  158.     }  
  159. }  

發佈了14 篇原創文章 · 獲贊 2 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章