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

Java反射技術詳解

 更新時間:2021年11月08日 16:13:18   作者:黃林晴  
這篇文章主要結合實例形式分析了介紹了Java反射技術,小編覺得這篇文章寫的還不錯,需要的朋友可以參考下,希望能夠給你帶來幫助

前言

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

一、基本反射技術

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

getClass方法

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

打印結果如下:

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) {
  }

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

打印結果如下:

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

Type屬性

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

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

二、獲取類的成員

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

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

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

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

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() {
    }

下面我們通過反射獲取這些構造方法

獲取類的所有構造方法

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

通過getDeclaredConstructors可以返回類的所有構造方法,返回的是一個數(shù)組因為構造方法可能不止一個,通過getModifiers可以得到構造方法的類型,getParameterTypes可以得到構造方法的所有參數(shù),返回的是一個Class數(shù)組,所以我們?nèi)绻氆@取所有構造方法以及每個構造方法的參數(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("");
  }

運行結果如下所示:

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

獲取類中特定的構造方法

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

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

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

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

這里要進行異常捕獲,因為可能不存在對應的構造方法,打印結果如下:

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

  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();
     }

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

調(diào)用構造方法

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

   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");

運行打印結果如下:

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

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

打印結果如下:

調(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[] = {"歡迎關注代碼男人技術公眾號"};
     method.invoke(test,arg1s);

test類的實例當不能new 獲取的時候我們也可以通過反射獲取,就是上面的newInstance方法。

打印結果如下:

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

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

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

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

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

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

最后反射封裝類如下:

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 {
    /**
     * 獲取無參構造函數(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;
    }
    /**
     * 獲取無參構造方法
     * @param clazz
     * @return
     */
    public static Object createObject(Class clazz) {
        Class[] pareTyple = new Class[]{};
        Object[] pareVaules = new Object[]{};
        return createObject(clazz, pareTyple, pareVaules);
    }
    /**
     * 獲取一個參數(shù)的構造函數(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ù)的構造方法 已知類
     *
     * @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ù)的構造方法 已知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;
    }
    /**
     * 獲取構造方法
     *
     * @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);
    }
}

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!

相關文章

  • FeignClient中name和url屬性的作用說明

    FeignClient中name和url屬性的作用說明

    這篇文章主要介紹了FeignClient中name和url屬性的作用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • struts2配置靜態(tài)資源代碼詳解

    struts2配置靜態(tài)資源代碼詳解

    這篇文章主要介紹了struts2配置靜態(tài)資源的相關內(nèi)容,文中涉及了具體代碼介紹,需要的朋友可以參考下。
    2017-09-09
  • SpringCloud?Nacos服務分級存儲模型詳解

    SpringCloud?Nacos服務分級存儲模型詳解

    Nacos服務分級存儲模型是Nacos存儲服務注冊信息和配置信息的核心模型之一,本文將對?Nacos?服務分級存儲模型進行深入解析,感興趣的朋友一起看看吧
    2024-02-02
  • 圖解Java排序算法之3種簡單排序

    圖解Java排序算法之3種簡單排序

    這篇文章主要為大家詳細介紹了Java排序算法之3種簡單排序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • springboot 如何解決static調(diào)用service為null

    springboot 如何解決static調(diào)用service為null

    這篇文章主要介紹了springboot 如何解決static調(diào)用service為null的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 不使用第三方變量交換兩個變量值的四種方法詳解

    Java 不使用第三方變量交換兩個變量值的四種方法詳解

    這篇文章主要介紹了四種不使用第三方變量交換兩個變量值的方法。文中對于四種方法進行了詳細的分析,需要的小伙伴們可以跟隨小編一起學習一下
    2021-12-12
  • java開發(fā)微信公眾號支付

    java開發(fā)微信公眾號支付

    這篇文章主要給大家結合微信支付接口開發(fā)的實踐,從獲取用戶授權到各主要接口的使用方法等方面介紹微信支付的關鍵點技術,有需要的小伙伴可以參考下
    2015-08-08
  • 解決SpringBoot在IDEA中熱部署失效問題

    解決SpringBoot在IDEA中熱部署失效問題

    熱部署是指程序運行過程中實時更新或替換其組件的技術,即項目正在啟動中,修改了配置文件中某個值或者添加了某個方法或者修改了某個方法參數(shù),本文給大家介紹了解決SpringBoot在IDEA中熱部署失效問題,需要的朋友可以參考下
    2024-01-01
  • 聊聊spring @Transactional 事務無法使用的可能原因

    聊聊spring @Transactional 事務無法使用的可能原因

    這篇文章主要介紹了spring @Transactional 事務無法使用的可能原因,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java socket大數(shù)據(jù)傳輸丟失問題及解決

    java socket大數(shù)據(jù)傳輸丟失問題及解決

    這篇文章主要介紹了java socket大數(shù)據(jù)傳輸丟失問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論

阜康市| 孝昌县| 无棣县| 军事| 萍乡市| 塔城市| 商河县| 东方市| 安国市| 枣强县| 临猗县| 丰镇市| 磴口县| 万全县| 根河市| 广汉市| 云龙县| 酒泉市| 临泉县| 乌兰察布市| 九龙县| 苗栗市| 四子王旗| 出国| 阿克陶县| 霍邱县| 科技| 道真| 玛纳斯县| 太和县| 乃东县| 手机| 什邡市| 凌海市| 张北县| 永兴县| 彭水| 高要市| 新闻| 成武县| 二手房|