<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kxbin
    成功留給有準備的人
    posts - 10,  comments - 35,  trackbacks - 0

    一、什么是反射:
    反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。這一概念的提出很快引發了計算機科學領域關于應用反射性的研究。它首先被程序語言的設計領域所采用,并在Lisp和面向對象方面取得了成績。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射機制的語言。最近,反射機制也被應用到了視窗系統、操作系統和文件系統中。

    反射本身并不是一個新概念,盡管計算機科學賦予了反射概念新的含義。在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過采用某種機制來實現對自己行為的描述(self-representation)和監測(examination),并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。

    二、什么是Java中的類反射:
    Reflection 是 Java 程序開發語言的特征之一,它允許運行中的 Java 程序對自身進行檢查,或者說“自審”,并能直接操作程序的內部屬性和方法。Java 的這一能力在實際應用中用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
    Reflection 是 Java 被視為動態(或準動態)語言的關鍵,允許程序于執行期 Reflection APIs 取得任何已知名稱之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于執行期生成instances、變更 fields 內容或喚起 methods。

    三、Java類反射中所必須的類:
    Java的類反射所需要的類并不多,它們分別是:Field、Constructor、Method、Class、Object,下面我將對這些類做一個簡單的說明。
    Field類:提供有關類或接口的屬性的信息,以及對它的動態訪問權限。反射的字段可能是一個類(靜態)屬性或實例屬性,簡單的理解可以把它看成一個封裝反射類的屬性的類。
    Constructor類:提供關于類的單個構造方法的信息以及對它的訪問權限。這個類和Field類不同,Field類封裝了反射類的屬性,而Constructor類則封裝了反射類的構造方法。
    Method類:提供關于類或接口上單獨某個方法的信息。所反映的方法可能是類方法或實例方法(包括抽象方法)。 這個類不難理解,它是用來封裝反射類方法的一個類。
    Class類:類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬于被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
    Object類:每個類都使用 Object 作為超類。所有對象(包括數組)都實現這個類的方法。

    四、Java的反射類能做什么:
    看完上面的這么多我想你已經不耐煩了,你以為我在浪費你的時間,那么好吧!下面我們就用一些簡單的小例子來說明它。
    首先我們來看一下通過Java的反射機制我們能得到些什么。
    首先我們來寫一個類:

    java 代碼
     
    import java.awt.event.ActionListener;   
    import java.awt.event.ActionEvent;   
    class A extends Object implements ActionListener{   
    private int a = 3;   
    public Integer b = new Integer(4);   
    public A(){}   
    public A(int id,String name){}   
    public int abc(int id,String name){return 0;}   
    public void actionPerformed(ActionEvent e){}   
    }  

    你可能被我這個類弄糊涂了,你看不出我要做什么,那就不要看這個類了,這個類是用來測試的,你知道知道它繼承了Object類,有一個接口是ActionListener,兩個屬性int和Integer,兩個構造方法和兩個方法,這就足夠了。
    下面我們把A這個類作為一個反射類,來過去A類中的一些信息,首先我們先來過去一下反射類中的屬性和屬性值。

    java 代碼
     
    import java.lang.reflect.*;   
    class B{   
    public static void main(String args[]){   
    A r = new A();   
    Class temp = r.getClass();   
    try{   
    System.out.println("反射類中所有公有的屬性");   
    Field[] fb =temp.getFields();   
    for(int j=0;j<fb.length;j++){   
    Class cl = fb[j].getType();   
    System.out.println("fb:"+cl);   
    }   
       
    System.out.println("反射類中所有的屬性");   
    Field[] fa = temp.getDeclaredFields();   
    for(int j=0;j<fa.length;j++){   
    Class cl = fa[j].getType();   
    System.out.println("fa:"+cl);   
    }   
    System.out.println("反射類中私有屬性的值");   
    Field f = temp.getDeclaredField("a");   
    f.setAccessible(true);   
    Integer i = (Integer)f.get(r);   
    System.out.println(i);   
    }catch(Exception e){   
    e.printStackTrace();   
    }   
    }   
       
    }   

    這里用到了兩個方法,getFields()、getDeclaredFields(),它們分別是用來獲取反射類中所有公有屬性和反射類中所有的屬性的方法。另外還有getField(String)和getDeclaredField(String)方法都是用來過去反射類中指定的屬性的方法,要注意的是getField方法只能取到反射類中公有的屬性,而getDeclaredField方法都能取到。
    這里還用到了Field 類的setAccessible方法,它是用來設置是否有權限訪問反射類中的私有屬性的,只有設置為true時才可以訪問,默認為false。另外 Field類還有set(Object AttributeName,Object value)方法,可以改變指定屬性的值。

    下面我們來看一下如何獲取反射類中的構造方法

    java 代碼
     
    import java.lang.reflect.*;   
    public class SampleConstructor {   
    public static void main(String[] args) {   
    A r = new A();   
    printConstructors(r);   
    }   
       
    public static void printConstructors(A r) {   
    Class c = r.getClass();   
    //獲取指定類的類名   
    String className = c.getName();   
    try {   
    //獲取指定類的構造方法   
    Constructor[] theConstructors = c.getConstructors();   
    for(int i=0; i<theConstructors.length; i++) {   
    //獲取指定構造方法的參數的集合   
    Class[] parameterTypes = theConstructors[i].getParameterTypes();   
       
    System.out.print(className + "(");   
       
    for(int j=0; j<parameterTypes.length; j++)   
    System.out.print(parameterTypes[j].getName() + " ");   
       
    System.out.println(")");   
       
    }   
    }catch(Exception e) {   
    e.printStackTrace();   
    }   
    }   
    }   
    這個例子很簡單,只是用getConstructors()方法獲取了反射類的構造方法的集合,并用Constructor類的getParameterTypes()獲取該構造方法的參數。

    下面我們再來獲取一下反射類的父類(超類)和接口

    java 代碼
     
    import java.io.*;   
    import java.lang.reflect.*;   
       
    public class SampleInterface {   
    public static void main(String[] args) throws Exception {   
    A raf = new A();   
    printInterfaceNames(raf);   
    }   
       
    public static void printInterfaceNames(Object o) {   
    Class c = o.getClass();   
    //獲取反射類的接口   
    Class[] theInterfaces = c.getInterfaces();   
    for(int i=0; i<theInterfaces.length; i++)   
    System.out.println(theInterfaces[i].getName());   
    //獲取反射類的父類(超類)   
    Class theSuperclass = c.getSuperclass();   
    System.out.println(theSuperclass.getName());   
    }   
    }  

    這個例子也很簡單,只是用Class類的getInterfaces()方法獲取反射類的所有接口,由于接口可以有多個,所以它返回一個 Class數組。用getSuperclass()方法來獲取反射類的父類(超類),由于一個類只能繼承自一個類,所以它返回一個Class對象。

    下面我們來獲取一下反射類的方法

    java 代碼
     
    import java.lang.reflect.*;   
    public class SampleMethod {   
       
    public static void main(String[] args) {   
    A p = new A();   
    printMethods(p);   
    }   
       
    public static void printMethods(Object o) {   
    Class c = o.getClass();   
    String className = c.getName();   
    Method[] m = c.getMethods();   
    for(int i=0; i<m.length; i++) {   
    //輸出方法的返回類型   
    System.out.print(m[i].getReturnType().getName());   
    //輸出方法名   
    System.out.print(" "+m[i].getName()+"(");   
    //獲取方法的參數   
    Class[] parameterTypes = m[i].getParameterTypes();   
    for(int j=0; j<parameterTypes.length; j++){   
    System.out.print(parameterTypes[j].getName());   
    if(parameterTypes.length>j+1){   
    System.out.print(",");   
    }   
    }   
       
    System.out.println(")");   
    }   
       
    }   
       
    }  

    這個例子并不難,它只是獲得了反射類的所有方法,包括繼承自它父類的方法。然后獲取方法的返回類型、方法名和方法參數。

    接下來讓我們回過頭來想一想,我們獲取了反射類的屬性、構造方法、父類、接口和方法,可這些東西能幫我們做些什么呢!!
    下面我寫一個比較完整的小例子,來說明Java的反射類能做些什么吧!!

    java 代碼
     
    import java.lang.reflect.Constructor;   
    import java.lang.reflect.Method;   
       
    public class LoadMethod {   
    public Object Load(String cName,String MethodName,String[] type,String[] param){   
    Object retobj = null;   
    try {   
    //加載指定的Java類   
    Class cls = Class.forName(cName);   
       
    //獲取指定對象的實例   
    Constructor ct = cls.getConstructor(null);   
    Object obj = ct.newInstance(null);   
       
    //構建方法參數的數據類型   
    Class partypes[] = this.getMethodClass(type);   
       
    //在指定類中獲取指定的方法   
    Method meth = cls.getMethod(MethodName, partypes);   
       
    //構建方法的參數值   
    Object arglist[] = this.getMethodObject(type,param);   
       
    //調用指定的方法并獲取返回值為Object類型   
    retobj= meth.invoke(obj, arglist);   
       
    }   
    catch (Throwable e) {   
    System.err.println(e);   
    }   
    return retobj;   
    }   
       
    //獲取參數類型Class[]的方法   
    public Class[] getMethodClass(String[] type){   
    Class[] cs = new Class[type.length];   
    for (int i = 0; i < cs.length; i++) {   
    if(!type[i].trim().equals("")||type[i]!=null){   
    if(type[i].equals("int")||type[i].equals("Integer")){   
    cs[i]=Integer.TYPE;   
    }else if(type[i].equals("float")||type[i].equals("Float")){   
    cs[i]=Float.TYPE;   
    }else if(type[i].equals("double")||type[i].equals("Double")){   
    cs[i]=Double.TYPE;   
    }else if(type[i].equals("boolean")||type[i].equals("Boolean")){   
    cs[i]=Boolean.TYPE;   
    }else{   
    cs[i]=String.class;   
    }   
    }   
    }   
    return cs;   
    }   
       
    //獲取參數Object[]的方法   
    public Object[] getMethodObject(String[] type,String[] param){   
    Object[] obj = new Object[param.length];   
    for (int i = 0; i < obj.length; i++) {   
    if(!param[i].trim().equals("")||param[i]!=null){   
    if(type[i].equals("int")||type[i].equals("Integer")){   
    obj[i]= new Integer(param[i]);   
    }else if(type[i].equals("float")||type[i].equals("Float")){   
    obj[i]= new Float(param[i]);   
    }else if(type[i].equals("double")||type[i].equals("Double")){   
    obj[i]= new Double(param[i]);   
    }else if(type[i].equals("boolean")||type[i].equals("Boolean")){   
    obj[i]=new Boolean(param[i]);   
    }else{   
    obj[i] = param[i];   
    }   
    }   
    }   
    return obj;   
    }   
    }  

    這是我在工作中寫的一個實現Java在運行時加載指定的類,并調用指定方法的一個小例子。這里沒有main方法,你可以自己寫一個。
    Load方法接收的五個參數分別是,Java的類名,方法名,參數的類型和參數的值。

    結束語:
    Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象,無需提前硬編碼目標類。這些特性使得反射特別適用于創建以非常普通的方式與對象協作的庫。Java reflection 非常有用,它使類和數據結構能按名稱動態檢索相關信息,并允許在運行著的程序中操作這些信息。Java 的這一特性非常強大,并且是其它一些常用語言,如 C、C++、Fortran 或者 Pascal 等都不具備的。

    但反射有兩個缺點。第一個是性能問題。用于字段和方法接入時反射要遠慢于直接代碼。性能問題的程度取決于程序中是如何使用反射的。如果它作為程序運行中相對很少涉及的部分,緩慢的性能將不會是一個問題。即使測試中最壞情況下的計時圖顯示的反射操作只耗用幾微秒。僅反射在性能關鍵的應用的核心邏輯中使用時性能問題才變得至關重要。

    posted on 2011-12-06 17:14 kxbin 閱讀(282) 評論(0)  編輯  收藏 所屬分類: java基礎
    你恨一個人是因為你愛他;你喜歡一個人,是因為他身上有你沒有的;你討厭一個人是因為他身上有你有的東西;你經常在別人面前批評某人,其實潛意識中是想接近他。

    <2025年7月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    常用鏈接

    留言簿(5)

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    J2EE

    java技術網站

    Linux

    平時常去的網站

    數據庫

    電影網站

    網站設計

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费视频爱爱太爽了| 又爽又高潮的BB视频免费看| 亚洲AⅤ优女AV综合久久久| 99久久免费精品高清特色大片| 亚洲区日韩区无码区| 亚洲一卡2卡三卡4卡有限公司| 一级毛片免费全部播放| 亚洲国产综合人成综合网站| 午夜亚洲国产精品福利| 一个人免费视频观看在线www| 国产亚洲精品国看不卡| 一区二区三区免费电影| 久久久精品国产亚洲成人满18免费网站| 日韩毛片免费一二三| 91视频国产免费| 亚洲乱亚洲乱妇无码| 情侣视频精品免费的国产| 亚洲国产精品无码中文字| 国产精品高清视亚洲一区二区| eeuss影院ss奇兵免费com| 国内自产拍自a免费毛片| 亚洲AV无码专区国产乱码不卡| **毛片免费观看久久精品| 亚洲国产超清无码专区| 成人免费无码大片A毛片抽搐| 国产亚洲欧美在线观看| 精品国产亚洲男女在线线电影 | 亚洲制服丝袜在线播放| 国产成人午夜精品免费视频| 亚洲精品色播一区二区| 亚洲高清最新av网站| 久久er国产精品免费观看2| 亚洲一区无码中文字幕乱码| 日本免费人成视频播放| 国产无遮挡又黄又爽免费网站| 老汉色老汉首页a亚洲| a级毛片无码免费真人| 亚洲成aⅴ人片在线观| 永久黄网站色视频免费直播| 亚洲AV无码一区二区三区人 | 亚洲AV永久无码精品|