Java中的反射,Java反射

來源:互聯網
上載者:User

Java中的反射,Java反射
Java反射API

Java反射指的是在運行狀態時,能夠擷取類的屬性和方法或者修改類運行時行為的過程。

java.lang.Class類提供了很多方法用於擷取中繼資料、檢查和改變類運行時的行為。

Java的反射主要涉及java.lang和java.lang.reflect包下的類。

反射應用情境舉例java.lang.Class類

java.lang.Class主要提供了以下兩個功能:

java.lang.Class類常用方法
Method Description
1) public String getName() 返回類名
2) public static Class forName(String className)throws ClassNotFoundException 載入類並返回Class對象
3) public Object newInstance()throws InstantiationException,IllegalAccessException 建立執行個體對象
4) public boolean isInterface() 判斷是否是介面
5) public boolean isArray() 判斷是否是數組
6) public boolean isPrimitive() 判斷是否是未經處理資料類型
7) public Class getSuperclass() 返回父類Class引用
8) public Field[] getDeclaredFields()throws SecurityException 返回類的成員屬性欄位數組
9) public Method[] getDeclaredMethods()throws SecurityException 返回類的方法數組
10) public Constructor[] getDeclaredConstructors()throws SecurityException 返回類的構造方法數組
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException 返回類中指定參數類型的方法
怎樣擷取Class對象

有三種方式,如下:

forName()方法樣本

可用於動態載入,當你知道類的全限定名時,可以使用該方式。注意未經處理資料類型不適用該方法;

package tmp;class Simple{}public class Test{    public static void main(String args[]) throws ClassNotFoundException    {        Class<?> c = Class.forName("tmp.Simple");        System.out.println(c.getName());        System.out.println(c.getSimpleName());    }}
tmp.Simple
Simple

getClass()方法樣本:

從執行個體對象中擷取Class對象

package tmp;class Simple{}public class Test{    void printName(Object obj)    {    }    public static void main(String args[])    {        Simple s = new Simple();        Class<? extends Object> c = s.getClass();        System.out.println(c.getName());        System.out.println(c.getSimpleName());    }}
tmp.Simple
Simple

.class文法樣本

作用於類名上,也可應用於未經處理資料類型,如下所示:

package tmp;public class Test{    public static void main(String args[])    {        Class<Boolean> c = boolean.class;        System.out.println(c.getName());        Class<Test> c2 = Test.class;        System.out.println(c2.getName());    }}
boolean
tmp.Test判斷Class對象對應的類型

以下方法可用於判斷Class對象對應的類型:

1) public boolean isInterface(): 是否對應介面
2) public boolean isArray(): 是否對應數組
3) public boolean isPrimitive(): 是否對應未經處理資料類型

程式碼範例:

package tmp;class Simple{}interface My{}public class Test{    public static void main(String args[])    {        try        {            Class<?> c = Class.forName("tmp.Simple");            System.out.println(c.isInterface());            Class<?> c2 = Class.forName("tmp.My");            System.out.println(c2.isInterface());        }        catch (Exception e)        {            System.out.println(e);        }    }}
false
true通過反射建立執行個體對象

有兩種方式,如下:

所以,通常來講,第二種方式比第一種使用範圍更廣。

Class對象調用newInstance()方法樣本

package tmp;class Simple{    void message()    {        System.out.println("Hello Java");    }}public class Test{    public static void main(String args[])    {        try        {            Class<?> c = Class.forName("tmp.Simple");            Simple s = (Simple) c.newInstance();            s.message();        }        catch (Exception e)        {            System.out.println(e);        }    }}
Hello Java

Constructor對象調用newInstance()方法樣本

注意這裡可以根據傳入參數的類型來得到指定的構造方法,還可以改變構造方法的存取權限限制。

package tmp;import java.lang.reflect.Constructor;class Simple{    private String msg;    void message()    {        System.out.println("Hello Java," + msg);    }    private Simple(String s){        this.msg = s;    }}public class Test{    public static void main(String args[])    {        try        {            Class<?> c = Class.forName("tmp.Simple");            Constructor<?> con = c.getDeclaredConstructor(String.class);            con.setAccessible(true);            Simple s = (Simple) con.newInstance("...");            s.message();        }        catch (Exception e)        {            System.out.println(e);        }    }}
Hello Java,...通過反射調用私人方法

通過反射,我們可以調用其它類的私人方法,主要涉及java.lang.Class和java.lang.reflect.Method類;

其中主要是用到了Method類的setAccessible方法和invoke方法,前者修改存取權限,後者調用方法。

通過調用有參私人方法樣本:

package tmp;import java.lang.reflect.Method;class A{    private void cube(int n)    {        System.out.println(n * n * n);    }}class Test{    public static void main(String args[]) throws Exception    {        Class<A> c = A.class;        Object obj = c.newInstance();        Method m = c.getDeclaredMethod("cube", new Class[]{ int.class });        m.setAccessible(true);        m.invoke(obj, 4);    }}
關於javap工具

使用javap命令可以反組譯碼java的位元組碼檔案,展示class檔案中的欄位屬性、構造方法、普通方法資訊;

使用說明:

javap java.lang.Object樣本

javap -c Test樣本:

寫個簡單的Test類,如下:

package tmp;class Simple{}public class Test{    public static void main(String args[])    {        System.out.println("Hello");    }}

輸入javap -c Test:

 參考資料

基本屬於翻譯,做了小部分修改

http://www.javatpoint.com/java-reflection

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.