大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 淺談Java反射的基本運用

淺談Java反射的基本運用

更新時間:2020-11-26 17:49:31 來源:動力節點 瀏覽1150次

Java反射(Reflection)就是在運行 Java 程序時,可以加載、探知、使用編譯期間完全未知的類。也就是說,Java 程序可以加載一個運行時才得知類名的類,獲得類的完整構造方法,并實例化出對象,給對象屬性設定值或者調用對象的方法。Java反射可以用于判斷任意對象所屬的類,獲得Class對象,構造任意一個對象以及調用一個對象。以此為基礎,我們來講一講Java反射的基本運用

 

1. 獲得Class對象

Class類的實例表示Java應用運行時的類(class and enum)或接口(interface and annotation)(每個Java類運行時都在JVM里表現為一個Class對象,可通過類名.class,類型.getClass(),Class.forName("類名")等方法獲取Class對象)。基本類型boolean,byte,char,short,int,long,float,double和關鍵字void同樣表現為Class對象。

聲明普通的Class對象,在編譯器并不會檢查Class對象的確切類型是否符合要求,如果存在錯誤只有在運行時才得以暴露出來。但是通過泛型聲明指明類型的Class對象,編譯器在編譯期將對帶泛型的類進行額外的類型檢查,確保在編譯期就能保證類型的正確性。

 

2.判斷是否為某個類的實例

一般地,我們用 instanceof 關鍵字來判斷是否為某個類的實例。同時我們也可以借助反射中 Class 對象的 isInstance() 方法來判斷是否為某個類的實例,它是一個 native 方法:

public native boolean isInstance(Object obj);

 

3.創建實例

使用Class對象的newInstance()方法來創建Class對象對應類的實例

classObj.newInstance() 只能夠調用public類型的無參構造函數,此方法是過時的。

Class<?> c = String.class;

Object str = c.newInstance();

先通過Class對象獲取指定的Constructor對象,再調用Constructor對象的newInstance()方法來創建實例。

可以根據傳入的參數,調用任意構造函數,在特定情況下,可以調用私有的構造函數,此方法是推薦使用的。

 

//獲取String所對應的Class對象

Class<?> c = String.class;

//獲取String類帶一個String參數的構造器

Constructor constructor = c.getConstructor(String.class);

//根據構造器創建實例

Object obj = constructor.newInstance("23333");

System.out.println(obj);

 

4.獲取方法

getMethods()

返回某個類的所有public方法,包括自己聲明和從父類繼承的。

getDeclaredMethods()

獲取所有本類自己的方法,不問訪問權限,不包括從父類繼承的方法

getMethod(String name, Class<?>... parameterTypes)

方法返回一個特定的方法,其中第一個參數為方法名稱,后面的參數為方法的參數對應Class的對象。

Method getDeclaredMethod(String name, Class<?>... params)

方法返回一個特定的方法,其中第一個參數為方法名稱,后面的參數為方法的參數對應Class的對象

 

操作私有方法

/**

 * 訪問對象的私有方法

 * 為簡潔代碼,在方法上拋出總的異常,實際開發別這樣

 */

private static void getPrivateMethod() throws Exception{

    //1. 獲取 Class 類實例

    TestClass testClass = new TestClass();

    Class mClass = testClass.getClass();

 

    //2. 獲取私有方法

    //第一個參數為要獲取的私有方法的名稱

    //第二個為要獲取方法的參數的類型,參數為 Class...,沒有參數就是null

    //方法參數也可這么寫 :new Class[]{String.class , int.class}

    Method privateMethod =

            mClass.getDeclaredMethod("privateMethod", String.class, int.class);

 

    //3. 開始操作方法

    if (privateMethod != null) {

        //獲取私有方法的訪問權

        //只是獲取訪問權,并不是修改實際權限

        privateMethod.setAccessible(true);

 

        //使用 invoke 反射調用私有方法

        //privateMethod 是獲取到的私有方法

        //testClass 要操作的對象

        //后面兩個參數傳實參

        privateMethod.invoke(testClass, "Java Reflect ", 666);

    }

}

 

5.獲取構造函數

Constructor[] getConstructors()

 

獲得類的所有公共構造函數

 

Constructor getConstructor(Class[] params)

 

獲得使用特殊的參數類型的公共構造函數,

 

Constructor[] getDeclaredConstructors()

 

獲得類的所有構造函數

 

Constructor getDeclaredConstructor(Class[] params)

 

獲得使用特定參數類型的構造函數

 

6. 獲取成員變量字段

Field[] getFields()

 

獲得類的所有公共字段

 

Field getField(String name)

 

獲得命名的公共字段

 

Field[] getDeclaredFields()

 

獲得類聲明的所有字段

 

Field getDeclaredField(String name)

 

獲得類聲明的命名的字段

 

修改私有變量

**

 * 修改對象私有變量的值

 * 為簡潔代碼,在方法上拋出總的異常

 */

private static void modifyPrivateFiled() throws Exception {

    //1. 獲取 Class 類實例

    TestClass testClass = new TestClass();

    Class mClass = testClass.getClass();

 

    //2. 獲取私有變量

    Field privateField = mClass.getDeclaredField("MSG");

 

    //3. 操作私有變量

    if (privateField != null) {

        //獲取私有變量的訪問權

        privateField.setAccessible(true);

 

        //修改私有變量,并輸出以測試

        System.out.println("Before Modify:MSG = " + testClass.getMsg());

 

        //調用 set(object , value) 修改變量的值

        //privateField 是獲取到的私有變量

        //testClass 要操作的對象

        //"Modified" 為要修改成的值

        privateField.set(testClass, "Modified");

        System.out.println("After Modify:MSG = " + testClass.getMsg());

    }

}


7.調用方法

當我們從類中獲取了一個方法后,我們就可以用 invoke() 方法來調用這個方法。invoke 方法的原型為:

public Object invoke(Object obj, Object... args)

        throws IllegalAccessException, IllegalArgumentException,

           InvocationTargetException

下面是一個實例

public class test1 {

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class<?> klass = methodClass.class;

        //創建methodClass的實例

        Object obj = klass.newInstance();

        //獲取methodClass類的add方法

        Method method = klass.getMethod("add",int.class,int.class);

        //調用method對應的方法 => add(1,4)

        Object result = method.invoke(obj,1,4);

        System.out.println(result);

    }

}

class methodClass {

    public final int fuck = 3;

    public int add(int a,int b) {

        return a+b;

    }

    public int sub(int a,int b) {

        return a+b;

    }

}


8.利用反射創建數組

數組在Java里是比較特殊的一種類型,它可以賦值給一個Object Reference。下面我們看一看利用反射創建數組的例子:

public static void testArray() throws ClassNotFoundException {

        Class<?> cls = Class.forName("java.lang.String");

        Object array = Array.newInstance(cls,25);

        //往數組里添加內容

        Array.set(array,0,"hello");

        Array.set(array,1,"Java");

        Array.set(array,2,"fuck");

        Array.set(array,3,"Scala");

        Array.set(array,4,"Clojure");

        //獲取某一項的內容

        System.out.println(Array.get(array,3));

    }


以上就是Java反射的基本運用,這些運用離不開Java反射的核心: JVM 在運行時才動態加載類或調用方法/訪問屬性,它不需要事先(寫代碼的時候或編譯期)知道運行對象是誰。對于Java反射的核心分析,可以觀看本站的Java基礎教程


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 欧美a视频| 国产理论自拍 | 成人亚洲性情网站www在线观看 | 干干日日 | 在线免费观看国产精品 | aaa级大片| 欧美激情 亚洲 | 国产69精品久久久久777 | 99久久www免费人成精品 | 欧美日韩亚洲综合久久久 | 91综合网| 口国产成人高清在线播放 | 久久九九亚洲精品 | 国产a自拍 | 国产羞羞羞视频在线观看 | 国产成人精品区在线观看 | www.天天射| 女人18特级一级毛片免费视频 | 国产精品久久久久免费a∨ 国产精品久久久久免费视频 | 日韩黄色网址 | 成人性生活视频 | 99精品国产综合久久久久 | 这里只有久久精品视频 | 国产成人在线小视频 | 成人国产在线观看 | 日本一级毛片毛片一级毛片 | 99热在线只有精品 | 欧美一级毛片视频 | 羞羞网站在线免费观看 | 国产精品videosse | 一级免费大片 | 91视频中文字幕 | 久久久精品免费热线观看 | 色婷婷综合久久久中文字幕 | 精品综合久久久久久97超人 | 国产一区三区二区中文在线 | 久久99精品久久久久子伦小说 | aaa级精品久久久国产片 | 国产好大好爽久久久久久久 | 日日添天天做天天爱 | 成 人国产在线观看高清不卡 |