最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java反射技術(shù)詳解及實例解析

 更新時間:2020年07月14日 14:21:00   作者:黃林晴  
這篇文章主要介紹了Java反射技術(shù)詳解及實例解析,反射可以說是Java中最強(qiáng)大的技術(shù)了,它可以做的事情太多太多,很多優(yōu)秀的開源框架都是通過反射完成的。如果對JAVA感興趣來可以學(xué)習(xí)一下

前言

  相信很多人都知道反射可以說是Java中最強(qiáng)大的技術(shù)了,它可以做的事情太多太多,很多優(yōu)秀的開源框架都是通過反射完成的,比如最初的很多注解框架,后來因為java反射影響性能,所以被運行時注解APT替代了,java反射有個開源框架jOOR相信很多人都用過,不過我們還是要學(xué)習(xí)反射的基礎(chǔ)語法,這樣才能自己寫出優(yōu)秀的框架,當(dāng)然這里所講的反射技術(shù),是學(xué)習(xí)Android插件化技術(shù)、Hook技術(shù)等必不可少的!

一、基本反射技術(shù)

      1.1 根據(jù)一個字符串得到一個類

        getClass方法

 String name = "Huanglinqing";
 Class c1 = name.getClass();
 System.out.println(c1.getName());

     打印結(jié)果如下:

    Class.forName

    比如我們獲取java.lang.String的類名 

 String name = "java.lang.String";
 Class c1 = null;
 try {
 c1 = Class.forName(name);
 System.out.println(c1.getName());
 } catch (ClassNotFoundException e) {
 }

這里也通過捕獲異常,因為我們傳的這個字符串可能不合法,字符串合法命名是類的命名空間和類的名稱組成

    打印結(jié)果如下:

我們還可以通過c1.getSuperclass()獲取到他的父類

   Type屬性

    基本類型都有type屬性,可以得到這個基本類型的類型,比如:

Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;

停停停!這些東西有啥子用,如此雞肋! 別急,一切都是為后續(xù)做準(zhǔn)備。

二、獲取類的成員

         當(dāng)類中方法定義為私有的時候我們能調(diào)用?不能!當(dāng)變量是私有的時候我們能獲取嗎?不能!但是反射可以,比如源碼中有你需要用到的方法,但是那個方法是私有的,這個時候你就可以通過反射去執(zhí)行這個私有方法,并且獲取私有變量。

       獲取類的構(gòu)造函數(shù)

       為了便于測試,我們定義一個Test類,Test類如下:(省略get和set方法)

       Test類中我們定義是三個私有變量,生成兩個公有的含參構(gòu)造方法和一個私有的含參構(gòu)造方法以及一個公有的無參構(gòu)造方法。

public class Test {
 
 private int age;
 private String name;
 private int testint;
 
 public Test(int age) {
 this.age = age;
 }
 
 public Test(int age, String name) {
 this.age = age;
 this.name = name;
 }
 
 private Test(String name) {
 this.name = name;
 }
 
 public Test() {
 }

      下面我們通過反射獲取這些構(gòu)造方法

       獲取類的所有構(gòu)造方法

 Test test = new Test();
 Class c4 = test.getClass();
 Constructor[] constructors ;
 constructors = c4.getDeclaredConstructors();

      通過getDeclaredConstructors可以返回類的所有構(gòu)造方法,返回的是一個數(shù)組因為構(gòu)造方法可能不止一個,通過getModifiers可以得到構(gòu)造方法的類型,getParameterTypes可以得到構(gòu)造方法的所有參數(shù),返回的是一個Class數(shù)組,所以我們?nèi)绻氆@取所有構(gòu)造方法以及每個構(gòu)造方法的參數(shù)類型,可以有如下代碼:

 for (int i = 0; i < constructors.length; i++) {
 System.out.print(Modifier.toString(constructors[i].getModifiers()) + "參數(shù):");
 Class[] parametertypes = constructors[i].getParameterTypes();
 for (int j = 0; j < parametertypes.length; j++) {
 System.out.print(parametertypes[j].getName() + " ");
 }
 System.out.println("");
 }

    運行結(jié)果如下所示:

    

    這樣我們就得到了類中所有構(gòu)造方法和構(gòu)造方法中的參數(shù),那么我們?nèi)绾潍@取特定的構(gòu)造方法呢?

    獲取類中特定的構(gòu)造方法

    我們可以通過getConstructors方法獲取類中 所有的public類型的構(gòu)造方法,代碼和上面一樣就不演示了。

    我們可以通過getDeclaredConstructor()方法傳參獲取特定參數(shù)類型的構(gòu)造方法,這里注意是getDeclaredConstructor()不是  getDeclaredConstructors() ,所以返回的是一個Class對象而不是一個Class數(shù)組。

    獲取無參構(gòu)造方法直接不傳參數(shù),如下所示:

 try {
 constructors = c4.getDeclaredConstructor();
 System.out.print(Modifier.toString(constructors.getModifiers()) + );
 } catch (NoSuchMethodException e) {
 e.printStackTrace();
 }

    這里要進(jìn)行異常捕獲,因為可能不存在對應(yīng)的構(gòu)造方法,打印結(jié)果如下:  

 

 如果我們想獲取有兩個參數(shù)分別為int和String類型的構(gòu)造方法,代碼如下:

 Class[] p = {int.class,String.class};
 try {
 constructors = c4.getDeclaredConstructor(p);
 System.out.print(Modifier.toString(constructors.getModifiers()) + "參數(shù):");
 Class[] parametertypes = constructors.getParameterTypes();
 for (int j = 0; j < parametertypes.length; j++) {
 System.out.print(parametertypes[j].getName() + " ");
 }
 } catch (NoSuchMethodException e) {
 e.printStackTrace();
 }

  這里我們同樣打印出構(gòu)造方法的參數(shù):

 

  調(diào)用構(gòu)造方法

   從這里開始慢慢到了關(guān)鍵的一步,得到類的實例,我們主要借助于newInstance方法,為了方便演示我們將測試類的兩個構(gòu)造方法打印出來. 

 public Test(int age, String name) {
 this.age = age;
 this.name = name;
 System.out.println("hello" + name + "i am" + age);
 }
 
 
 private Test(String name) {
 this.name = name;
 System.out.println("My Name is" +
 name);
 }

   我們先來調(diào)用public的方法,如下所示:

 Class[] p = {int.class,String.class};
 constructors = c4.getDeclaredConstructor(p);
 constructors.newInstance(24,"HuangLinqing");

 運行打印結(jié)果如下:

  

 那么調(diào)用私有構(gòu)造方法呢,和上面一樣,只是我們要設(shè)置constructors.setAccessible(true);代碼如下:

 Class[] p = {String.class};
 constructors = c4.getDeclaredConstructor(p);
 constructors.setAccessible(true);
 constructors.newInstance("HuangLinqing");

打印結(jié)果如下:


調(diào)用類的私有方法

  如何調(diào)用類中的私有方法呢,我們先在測試類中編寫一個測試的私有方法 如下:

 private void welcome(String tips){
 System.out.println(tips);
 }

  我們知道如果我們要正常的調(diào)用類的方法都是通過類.方法調(diào)用,所以我們調(diào)用私有方法也需要得到類的實例,而我們上面newInstace已經(jīng)得到了類的實例,這樣就好辦了。

Class[] p4 = {String.class};
 Method method = c4.getDeclaredMethod("welcome",p4);
 method.setAccessible(true);

   我們首先通過 getDeclaredMethod方法獲取到這個私有方法,第一個參數(shù)是方法名,第二個參數(shù)是參數(shù)類型

   然后通過invoke方法執(zhí)行,invoke需要兩個參數(shù)一個是類的實例,一個是方法參數(shù)。    

Class[] p4 = {String.class};
 Method method = c4.getDeclaredMethod("welcome",p4);
 method.setAccessible(true);
 Object arg1s[] = {"歡迎關(guān)注代碼男人技術(shù)公眾號"};
 method.invoke(test,arg1s);

     test類的實例當(dāng)不能new 獲取的時候我們也可以通過反射獲取,就是上面的newInstance方法。打印結(jié)果如下:


 獲取類的私有字段并修改值

  看到這里你可能會說,有了set方法,什么私有不私有,test.set不就可以了,但是這里要注意我們是沒有辦法得到這個類的實例的,要不然都可以得到實例就沒有反射一說了。我們在通過反射得到類的實例之后先獲取字段:

Field field = c4.getDeclaredField("name");
field.setAccessible(true);
field.set(o,"代碼男人");

   o是我們上面通過反射構(gòu)造方法獲取的實例,  打印field.get(o).toString()的值如下:

   

   不過要注意的是我們修改了name的值只對當(dāng)前的實例對象有效。

   Java的基本反射語法就是這樣了,歡迎加入技術(shù)群一起探討!

  最后反射封裝類如下:

package jnidemo.hlq.com.hookdemo;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
 
/**
 * @author Huanglinqing
 * @date 2019/4/28
 */
 
public class Reflex {
 
 /**
 * 獲取無參構(gòu)造函數(shù)
 * @param className
 * @return
 */
 public static Object createObject(String className) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 try {
 Class r = Class.forName(className);
 return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 獲取無參構(gòu)造方法
 * @param clazz
 * @return
 */
 public static Object createObject(Class clazz) {
 Class[] pareTyple = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return createObject(clazz, pareTyple, pareVaules);
 }
 
 /**
 * 獲取一個參數(shù)的構(gòu)造函數(shù) 已知className
 *
 * @param className
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object createObject(String className, Class pareTyple, Object pareVaule) {
 
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 try {
 Class r = Class.forName(className);
 return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取單個參數(shù)的構(gòu)造方法 已知類
 *
 * @param clazz
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object createObject(Class clazz, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return createObject(clazz, pareTyples, pareVaules);
 }
 
 /**
 * 獲取多個參數(shù)的構(gòu)造方法 已知className
 * @param className
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) {
 try {
 Class r = Class.forName(className);
 return createObject(r, pareTyples, pareVaules);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取構(gòu)造方法
 *
 * @param clazz
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object createObject(Class clazz, Class[] pareTyples, Object[] pareVaules) {
 try {
 Constructor ctor = clazz.getDeclaredConstructor(pareTyples);
 ctor.setAccessible(true);
 return ctor.newInstance(pareVaules);
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 
 /**
 * 獲取多個參數(shù)的方法
 * @param obj
 * @param methodName
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) {
 if (obj == null) {
 return null;
 }
 
 try {
 //調(diào)用一個private方法 //在指定類中獲取指定的方法
 Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples);
 method.setAccessible(true);
 return method.invoke(obj, pareVaules);
 
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 獲取一個參數(shù)的方法
 * @param obj
 * @param methodName
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = {pareTyple};
 Object[] pareVaules = {pareVaule};
 
 return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules);
 }
 
 /**
 * 獲取無參方法
 * @param obj
 * @param methodName
 * @return
 */
 public static Object invokeInstanceMethod(Object obj, String methodName) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules);
 }
 
 
 /**
 * 無參靜態(tài)方法
 * @param className
 * @param method_name
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeStaticMethod(className, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 獲取一個參數(shù)的靜態(tài)方法
 * @param className
 * @param method_name
 * @param pareTyple
 * @param pareVaule
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name, Class pareTyple, Object pareVaule) {
 Class[] pareTyples = new Class[]{pareTyple};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return invokeStaticMethod(className, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 獲取多個參數(shù)的靜態(tài)方法
 * @param className
 * @param method_name
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) {
 try {
 Class obj_class = Class.forName(className);
 return invokeStaticMethod(obj_class, method_name, pareTyples, pareVaules);
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 /**
 * 無參靜態(tài)方法
 * @param method_name
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name) {
 Class[] pareTyples = new Class[]{};
 Object[] pareVaules = new Object[]{};
 
 return invokeStaticMethod(clazz, method_name, pareTyples, pareVaules);
 }
 
 /**
 * 一個參數(shù)靜態(tài)方法
 * @param clazz
 * @param method_name
 * @param classType
 * @param pareVaule
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name, Class classType, Object pareVaule) {
 Class[] classTypes = new Class[]{classType};
 Object[] pareVaules = new Object[]{pareVaule};
 
 return invokeStaticMethod(clazz, method_name, classTypes, pareVaules);
 }
 
 /**
 * 多個參數(shù)的靜態(tài)方法
 * @param clazz
 * @param method_name
 * @param pareTyples
 * @param pareVaules
 * @return
 */
 public static Object invokeStaticMethod(Class clazz, String method_name, Class[] pareTyples, Object[] pareVaules) {
 try {
 Method method = clazz.getDeclaredMethod(method_name, pareTyples);
 method.setAccessible(true);
 return method.invoke(null, pareVaules);
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 
 public static Object getFieldObject(String className, Object obj, String filedName) {
 try {
 Class obj_class = Class.forName(className);
 return getFieldObject(obj_class, obj, filedName);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 return null;
 }
 
 public static Object getFieldObject(Class clazz, Object obj, String filedName) {
 try {
 Field field = clazz.getDeclaredField(filedName);
 field.setAccessible(true);
 return field.get(obj);
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 return null;
 }
 
 
 public static void setFieldObject(Class clazz, Object obj, String filedName, Object filedVaule) {
 try {
 Field field = clazz.getDeclaredField(filedName);
 field.setAccessible(true);
 field.set(obj, filedVaule);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 
 public static void setFieldObject(String className, Object obj, String filedName, Object filedVaule) {
 try {
 Class obj_class = Class.forName(className);
 setFieldObject(obj_class, obj, filedName, filedVaule);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 }
 
 
 public static Object getStaticFieldObject(String className, String filedName) {
 return getFieldObject(className, null, filedName);
 }
 
 public static Object getStaticFieldObject(Class clazz, String filedName) {
 return getFieldObject(clazz, null, filedName);
 }
 
 public static void setStaticFieldObject(String classname, String filedName, Object filedVaule) {
 setFieldObject(classname, null, filedName, filedVaule);
 }
 
 public static void setStaticFieldObject(Class clazz, String filedName, Object filedVaule) {
 setFieldObject(clazz, null, filedName, filedVaule);
 }
}

到此這篇關(guān)于Java反射技術(shù)詳解及實例解析的文章就介紹到這了,更多相關(guān)Java反射技術(shù)示例詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring監(jiān)視器actuator配置應(yīng)用

    spring監(jiān)視器actuator配置應(yīng)用

    這篇文章主要介紹了spring監(jiān)視器actuator配置應(yīng)用,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Java 全面系統(tǒng)介紹反射的運用

    Java 全面系統(tǒng)介紹反射的運用

    準(zhǔn)備入手學(xué)習(xí)java的安全了,感覺這也是一個大的趨勢,想著盡早進(jìn)入到j(luò)ava安全的探索中,在反序列化鏈的學(xué)習(xí)之前,需要先學(xué)習(xí)反射,不多說了,開干吧
    2022-03-03
  • Java連接各種數(shù)據(jù)庫的方法

    Java連接各種數(shù)據(jù)庫的方法

    這篇文章主要介紹了Java連接各種數(shù)據(jù)庫的方法,實例分析了java連接MySQL、SQL Server、Sysbase、Oracle、PostgreSQL及DB2等數(shù)據(jù)庫的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Java多線程死鎖示例

    Java多線程死鎖示例

    這篇文章主要介紹了Java多線程死鎖,結(jié)合實例形式分析了Java多線程出現(xiàn)死鎖的相關(guān)原因與操作注意事項,需要的朋友可以參考下
    2018-08-08
  • SpringBoot根據(jù)目錄結(jié)構(gòu)自動生成路由前綴的實現(xiàn)代碼

    SpringBoot根據(jù)目錄結(jié)構(gòu)自動生成路由前綴的實現(xiàn)代碼

    本文介紹如何根據(jù)目錄結(jié)構(gòu)給RequestMapping添加路由前綴,具體實現(xiàn)方法,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • springboot整合阿里云oss上傳的方法示例

    springboot整合阿里云oss上傳的方法示例

    這篇文章主要介紹了springboot整合阿里云oss上傳的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 解析Java并發(fā)Exchanger的使用

    解析Java并發(fā)Exchanger的使用

    Exchanger是java 5引入的并發(fā)類,Exchanger顧名思義就是用來做交換的。這里主要是兩個線程之間交換持有的對象。當(dāng)Exchanger在一個線程中調(diào)用exchange方法之后,會等待另外的線程調(diào)用同樣的exchange方法。兩個線程都調(diào)用exchange方法之后,傳入的參數(shù)就會交換。
    2021-06-06
  • Mybatis中的自定義映射resultMap

    Mybatis中的自定義映射resultMap

    在MyBatis中,自定義映射resultMap可以讓你精確控制如何將數(shù)據(jù)庫返回的結(jié)果集映射到Java對象上,本文給介紹了Mybatis之自定義映射resultMap,需要的朋友可以參考下
    2024-03-03
  • Java8學(xué)習(xí)教程之lambda表達(dá)式語法介紹

    Java8學(xué)習(xí)教程之lambda表達(dá)式語法介紹

    眾所周知lambda表達(dá)式是JAVA8中提供的一種新的特性,它支持Java也能進(jìn)行簡單的“函數(shù)式編程”。 下面這篇文章主要給大家介紹了關(guān)于Java8學(xué)習(xí)教程之lambda表達(dá)式語法的相關(guān)資料,需要的朋友可以參考下。
    2017-09-09
  • javaweb中mysql數(shù)據(jù)庫連接步驟方法及其實例

    javaweb中mysql數(shù)據(jù)庫連接步驟方法及其實例

    這篇文章主要介紹了使用java web 連接MySQL數(shù)據(jù)庫的驅(qū)動方法的相關(guān)知識,本文介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下
    2017-04-04

最新評論

侯马市| 枞阳县| 五家渠市| 福鼎市| 汝阳县| 重庆市| 离岛区| 邓州市| 海淀区| 沧州市| 古蔺县| 苏尼特右旗| 榆林市| 孝昌县| 花莲县| 临海市| 江门市| 读书| 滨海县| 浙江省| 白沙| 闽清县| 沈阳市| 基隆市| 阿城市| 常德市| 盐边县| 自贡市| 福建省| 西昌市| 娱乐| 温宿县| 宜君县| 灵山县| 蓬安县| 宁陵县| 武邑县| 福安市| 南部县| 汽车| 阆中市|