Java 反射机制详解:私有方法调用头大?如何通过反射调用类中的私有方法?
文章目錄
- 前言
- 一、私有方法在本類中直接調(diào)用
- 1.1、在本類中實(shí)例化,調(diào)用私有方法
- 1.2、嘗試在其他類直接調(diào)用私有方法(錯(cuò)誤示范)
- 二、使用反射實(shí)例化類強(qiáng)制調(diào)用私有方法
- 2.1、使用類加載器加載被調(diào)用的類
- 2.2、使用 Object 類對(duì)獲取的類進(jìn)行實(shí)例化
- 2.3、調(diào)用 Java 反射中的 Method 類
- 2.4、取消 Java 語言的訪問檢查
- 2.5、使用 method 方法返回對(duì)象
- 三、完整實(shí)現(xiàn)代碼、運(yùn)行結(jié)果
- 總結(jié)
前言
在 Java 中如果我們使用 new 關(guān)鍵字調(diào)用構(gòu)造函數(shù)對(duì)類進(jìn)行實(shí)例化,我們就可以根據(jù)在這個(gè)類中的修飾符來訪問類中定義的非私有方法。但是如果需要在其他類調(diào)用私有的方法,就可以利用 Java 中提供的反射來實(shí)現(xiàn)。一、私有方法在本類中直接調(diào)用
1.1、在本類中實(shí)例化,調(diào)用私有方法
說明:被 private 關(guān)鍵字修飾的構(gòu)造方法、方法或者數(shù)據(jù)域只在其所在的類中可見。
如下,我們創(chuàng)建一個(gè) Demo 類,并定義一個(gè)私有的方法 demo(),使用 main 函數(shù)在本類中使用 new 關(guān)鍵字實(shí)例化類,去調(diào)用 demo() 方法,運(yùn)行成功輸出結(jié)果,代碼如下:
package com.bailu.demo;public class Demo {private void demo() {System.out.println("私有方法!");}// 私有方法只有在本類中可以訪問public static void main(String[] args) {Demo demo = new Demo();demo.demo();} }1.2、嘗試在其他類直接調(diào)用私有方法(錯(cuò)誤示范)
如果我們直接在其他的類中實(shí)例化 Demo 類,來直接調(diào)用 demo() 方法,就會(huì)發(fā)現(xiàn) IDE 直接產(chǎn)生編譯錯(cuò)誤,很明顯我們直接在另一個(gè)類中調(diào)用私有方法是行不通的,IDE 提示我們把 private 修飾符去掉,這又是不滿足我們需求的,如下圖所示:
二、使用反射實(shí)例化類強(qiáng)制調(diào)用私有方法
2.1、使用類加載器加載被調(diào)用的類
Class<?> cls = Class.forName("com.bailu.demo.Demo");說明:這里的Class<?> 即為 Java 中的泛型。以下是我們?cè)陂_發(fā)中常見的幾種泛型:
- ? 表示不確定的 Java 類型
- T 表示 Java 類型
- K V 分別代表 Java 鍵值中的 Key Value
- E 代表 Element
2.2、使用 Object 類對(duì)獲取的類進(jìn)行實(shí)例化
Object obj = cls.newInstance();說明:Object是所有類的根類,是具體的一個(gè)類,使用的時(shí)候可能需要類型強(qiáng)制轉(zhuǎn)換的,但是用通配符 ?、T 、K 、V、 E 等這些的話,在實(shí)際用之前類型就已經(jīng)確定了,不需要強(qiáng)制轉(zhuǎn)換。
2.3、調(diào)用 Java 反射中的 Method 類
Method method = cls.getDeclaredMethod("demo", null);說明:Method類是java.lang.reflect中提供的一個(gè)類。我們通過實(shí)例化Method類來調(diào)用Method類中的方法,常用方法有以下幾個(gè):
- getMethods():獲得類的 public 類型的方法
- getMethod(String name, Class[] params):獲得類的特定方法,name 參數(shù)指定方法的名字,params 參數(shù)指定方法的參數(shù)類型
- getDeclaredMethods():獲取類中所有的方法(public、protected、default、private)
- getDeclaredMethod(String name, Class[] params):獲得類的特定方法,name 參數(shù)指定方法的名字,params 參數(shù)指定方法的參數(shù)類型
這里我們調(diào)用第四個(gè)獲取 Demo 類的 demo() 方法,參數(shù)類型為 null。
2.4、取消 Java 語言的訪問檢查
method.setAccessible(true);setAccessible(true/false):表示禁用和啟用安全檢查的開關(guān)。
說明:當(dāng)值為true時(shí),指反射對(duì)象在使用時(shí)應(yīng)該取消 Java 語言訪問檢查,值為false則只是反射的對(duì)象應(yīng)該試試 Java 語言訪問檢查。當(dāng)值設(shè)置為true時(shí),不接受檢查,可以提高反射的運(yùn)行速度。
2.5、使用 method 方法返回對(duì)象
使用 method.invoke(Object obj,Object args[]);返回對(duì)象,強(qiáng)制執(zhí)行對(duì)象中的目標(biāo)方法,代碼如下:
method.invoke(obj, null);說明:Method類的invoke(Object obj,Object args[])方法接收的參數(shù)必須為對(duì)象,如果參數(shù)為基本類型數(shù)據(jù),必須轉(zhuǎn)換為相應(yīng)的包裝類型的對(duì)象。invoke()方法的返回值總是對(duì)象,如果實(shí)際被調(diào)用的方法的返回類型是基本類型數(shù)據(jù),那么invoke()方法會(huì)把它轉(zhuǎn)換為相應(yīng)的包裝類型的對(duì)象,再將其返回。
三、完整實(shí)現(xiàn)代碼、運(yùn)行結(jié)果
Demo 類:
package com.bailu.demo;public class Demo {private void demo() {System.out.println("私有方法!");}// 私有方法只有在本類中可以訪問public static void main(String[] args) {Demo demo = new Demo();demo.demo();} }TestDemo 類:
package com.bailu.demo;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class TestDemo {public static void main(String[] args) throws ClassNotFoundException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 1、使用類加載器加載被調(diào)用的類Class<?> cls = Class.forName("com.bailu.demo.Demo");// 2、使用Object類對(duì)獲取的類進(jìn)行實(shí)例化Object obj = cls.newInstance();// 將異常拋出try {// 3、調(diào)用Java反射中的Method類,將私有方法封裝在obj中Method method = cls.getDeclaredMethod("demo", null);// 取消 Java 語言的訪問檢查method.setAccessible(true);// 4、使用method.invoke(Object obj,Object args[]);返回對(duì)象method.invoke(obj, null);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}} }運(yùn)行結(jié)果如下圖所示:
總結(jié)
在我們的開發(fā)過程中,通常只有實(shí)體類(Entity)中的成員變量使用 private 修飾,并且會(huì)提供訪問這些變量的 get 和 set 方法。原則上要求不準(zhǔn)定義私有的方法,我們使用 method.invoke(Object obj,Object args[]); 強(qiáng)制調(diào)用對(duì)象調(diào)用私有方法違反了我們 Java 中面向?qū)ο蟮奶匦浴?我是白鹿,一個(gè)不懈奮斗的程序猿。望本文能對(duì)你有所裨益,歡迎大家的一鍵三連!若有其他問題、建議或者補(bǔ)充可以留言在文章下方,感謝大家的支持!
總結(jié)
以上是生活随笔為你收集整理的Java 反射机制详解:私有方法调用头大?如何通过反射调用类中的私有方法?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 荣威发动机质量怎么样 评价荣威发动机质量
- 下一篇: Java GUI 实现登录界面