1. 程式人生 > >java黑魔法-反射機制-01

java黑魔法-反射機制-01

out 什麽 static 映射 靜態 alt 編譯 自動 long

技術分享

技術分享

在java的幫助文檔中,java.lang包中有一個Class類,註意這裏的"C“是大寫,所以這個不是表示類的聲明,而是一個真正的類。在java的幫助文檔中,這樣定義的Class類:

public final class Class<T>extends Objectimplements Serializable, GenericDeclaration, Type, AnnotatedElement

Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,註釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該Class 對象。基本的 Java 類型(boolean、byte、char、short、int、long、float 和double)和關鍵字 void 也表示為 Class 對象。 Class 沒有公共構造方法。Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的defineClass 方法自動構造的。

在Java中,每個class都有一個相應的Class對象。也就是說,當我們編寫一個類,編譯完成後,在生成的.class文件中,就會產生一個Class對象,用於表示這個類的類型信息。Class類不是我們人為創建的,是由java虛擬機,在我們生成.class文件的時候創建的,我們可以通過幾種方法,獲得這個Class類實例。下面介紹一下這幾種方法:



(1)利用對象調用getClass()方法獲取該對象的Class實例;
(2)使用Class類的靜態方法forName(),用類的名字獲取一個Class實例;
(3)運用.class的方式來獲取Class實例,對於基本數據類型的封裝類,還可以采用.TYPE來獲取相對應的基本數據類型的Class實例。下面的是一個實例

package com.aaron.reflect;

class Point {
    int age;
    public void say(){
        System.out.println(123);
    }
}

public class test {
    
public static void main(String args[]) { System.out.println(new Point().getClass());//class com.aaron.reflect.Point 而且有方法say // Class<?> c11 =(Class<?>)new Point(); 不可以這麽轉換 Point pt = new Point(); Class<?> c1 = pt.getClass(); // 這個方法經常常見,c1,也沒有這個方法 System.out.println("100"+c1.getName()); //
com.aaron.reflect.Point try {// forName會拋出一個異常所以需要捕獲,必須加上包的路徑 Class<?> c2 = Class.forName("com.aaron.reflect.Point"); System.out.println("101"+c2.getName());//com.aaron.reflect.Point //System.out.println(c2.say());並沒有這個方法 } catch (Exception e) { e.printStackTrace(); } Class<?> c3 = Point.class; System.out.println("000"+c3.getName()); // com.aaron.reflect.Point Class<?> c4 = int.class; System.out.println("001"+c4.getName()); // int Class<?> c5 = Integer.TYPE; System.out.println("002"+c5.getName()); // int Class<?> c6 = Integer.class; //每個類都可以看成Class這個類的對象,運用.class的方式來獲取Class實例 System.out.println("003"+c6.getName()); // 003java.lang.Integer } }


在運行期間,如果我們要產生某個類的對象,Java虛擬機(JVM)會檢查該類型的Class對象是否已被加載。如果沒有被加載,JVM會根據類的名稱找到.class文件並加載它。一旦某個類型的Class對象已被加載到內存,就可以用它來產生該類型的所有對象。換句話說java中的.class文件並不是所有的都會被加載到內存,只有在需要的時候才會進行加載。

Class類有一方法newInstance(),可以在不知道類的名字的情況下創建一個對象。使用newInstance()的方法的時候,應該註意這個方法默認調用的是不帶參數的構造方法。如果只是去創建一個一個不帶參數的構造方法,那麽這個方法的用處就不大了,如果我們想要調用帶參數的構造方法,這裏我們就需要使用到反色API。對於反色API的介紹,查看我先前轉載的一篇文章(http://blog.csdn.net/mengxiangyue/article/details/6825923)。有時候我們會收到一個通過網絡發來的一個類,我們需要創建一個對象,但是對於這個類是怎麽實現的,我們都不知道。這裏我們就可以使用反色API加上Class類的newInstance(),在不知道類的情況下,創建一個對象。對於這個Class的用處目前就知道這麽多,如果還有什麽,希望有大俠指點。

java黑魔法-反射機制-01