欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot工具類ReflectionUtils使用教程

 更新時間:2022年12月30日 10:58:46   作者:凡夫販夫  
這篇文章主要介紹了Springboot內(nèi)置的工具類之ReflectionUtils的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

前言

ReflectionUtils應(yīng)該是Springboot內(nèi)置工具類梳理的最后一篇了,可能很多人都沒有聽說過這個工具類,這個類封裝的是一些與java反射相關(guān)的靜態(tài)工具方法??赡芎芏嗳艘仓婪瓷?,卻不怎么經(jīng)常使用反射。其實反射是一個很有用的技術(shù)點,我認(rèn)為是可以和AOP比肩的,甚至有過之而不及。大家都知道AOP是面向切面編程,可以在定義的切面前、后執(zhí)行一些操作,但是反射更厲害,它可以在程序運行時,對已裝載的任意類的屬性和方法進行操作,這就是java的反射機制。

ReflectionUtils

org.springframework.util.ReflectionUtils中包含的靜態(tài)方法其實有很多,主要分為兩類:對類中屬性的操作和對類中方法的操作。

對屬性的操作

獲取屬性字段

Field findField(Class clazz,Stringname),在類中查找指定屬性。

@Test
public void test1(){
    //查找屬性字段realName
    Field realName = ReflectionUtils.findField(Employee.class, "realName");
    Assert.notNull(realName, "獲取員工類的姓名屬性失敗");
}

Field findField(Class clazz,Stringname, Classtype),更精確的在類中查找指定屬性,可以在指定屬性的類型。

@Test
public void test2(){
     //查找屬性字段realName,類型是String
    Field realName = ReflectionUtils.findField(Employee.class, "realName",String.class);
    Assert.notNull(realName, "獲取員工類的姓名屬性失敗");
}

設(shè)置屬性字段的值

ObjectgetField(Field field,Objecttarget),獲取 target 對象的 field 屬性值。

@Test
public void test3() {
    //聲名一個對象,姓名是zhangsan
    Employee zhangsan = new Employee("zhangsan");
    //獲取Employee類中的realName屬性字段
    Field field = ReflectionUtils.findField(Employee.class, "realName");
    //取消realName屬性的private權(quán)限控制
    ReflectionUtils.makeAccessible(field);
    //獲取員工對象的姓名字段的值
    Object value = ReflectionUtils.getField(field, zhangsan);
    Assert.isTrue(value.equals("zhangsan"),"員工zhangsan的姓名字段取值失敗" );
}

voidsetField(Field field,Objecttarget,Objectvalue),可以設(shè)置 target 對象的 field 屬性值,值為 value。

@Test
public void test4() {
    Employee zhangsan = new Employee("zhangsan");
    //獲取Employee類中的realName屬性字段
    Field field = ReflectionUtils.findField(Employee.class, "realName");
    //取消realName屬性的private權(quán)限控制
    ReflectionUtils.makeAccessible(field);
    //把員工對象zhangsan的姓名字段值設(shè)置為zhangsan_v2
    ReflectionUtils.setField(field, zhangsan, "zhangsan_v2");
    Object value = ReflectionUtils.getField(field, zhangsan);
    Assert.isTrue(value.equals("zhangsan_v2"),"員工zhangsan的姓名字段取值失敗" );
}

voidshallowCopyFieldState(Objectsrc,Objectdest),如果兩個對象是同一個類的實現(xiàn),且希望把一對象的值復(fù)制到另外一個對象上,可以使用這個方法,src是源對象,dest是目標(biāo)對象。

@Test
public void test5() {
    Employee zhangsan = new Employee("zhangsan");
    Employee tmp = new Employee();
    //把對象zhangsan的值復(fù)制到對象tmp上,這里要注意,復(fù)制的對象類型要相同
    ReflectionUtils.shallowCopyFieldState(zhangsan, tmp);
    Assert.isTrue(tmp.getRealName().equals("zhangsan"),"對象的屬性復(fù)制失敗了" );
}

voidmakeAccessible(Field field),取消java的權(quán)限控制檢查,方便private私有訪問權(quán)限的操作。

@Test
public void test4() {
    Employee zhangsan = new Employee("zhangsan");
    //取消realName屬性的private權(quán)限控制
    ReflectionUtils.makeAccessible(field);
}

voiddoWithFields(Class clazz, ReflectionUtils.FieldCallback fc),可以對類的每個屬性執(zhí)行 回調(diào)方法,簡單的理解就是可以定義一個回調(diào)方法,在對類的屬性操作完后,回調(diào)方法內(nèi)的邏輯就會被執(zhí)行。另外還有兩個方法,功能也很類似:void doWithFields(Class clazz, ReflectionUtils.FieldCallback fc,ReflectionUtils.FieldFilter ff),不僅有回調(diào)方法,還可以增加過濾的邏輯;voiddoWithLocalFields(Class clazz, ReflectionUtils.FieldCallback fc),只對本類的屬性可以執(zhí)行回調(diào)方法,不包括父類的。舉個例子,簡單的理解一下,實在理解不了就放棄吧,因為我也覺得這個確實有點雞肋。假如員的性別在程序中是以1和0進行區(qū)分,對外展示的時候要轉(zhuǎn)換為“男”和“女”:

public class  SexFieldCallBack<T>  implements ReflectionUtils.FieldCallback{
    private Object obj;
    private Integer sexFlag=-1;
    public SexFieldCallBack(Object obj) {
        this.obj = obj;
    }
    @Override
    public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        field.setAccessible(true);
        if (field.getName().equals("sexFlag")) {
            Object value = field.get(obj);
            this.sexFlag= ((Integer) value);
        }
        if(field.getName().equals("sex")){
            if (1==this.sexFlag) {
                field.set(obj, "男");
            }
            if (0==this.sexFlag) {
                field.set(obj, "女");
            }
        }
    }
}
@Test
public void test6() throws IllegalAccessException, InstantiationException {
    Employee employee = Employee.class.newInstance();
    employee.setRealName("zhangsan");
    //性別標(biāo)志位,1:男,0:女
    employee.setSexFlag(1);
    ReflectionUtils.doWithFields(Employee.class,new SexFieldCallBack(employee) );
    Assert.isTrue("男".equals(employee.getSex()), "性別轉(zhuǎn)換失敗了");
}

對方法的操作

@Data
public class Employee implements Serializable {
    private String realName;
    public void hello(String name) {
        System.out.println(name + ",你好!我是" + this.realName);
    }
    public void say(String name) {
        System.out.println(name + ",你好!我是" + this.realName);
    }
    public String hello(String name, Boolean isReturn) {
        String msg = name + ",你好!我是" + this.realName;
        if (isReturn) {
            System.out.println(msg);
            return msg;
        }
        return null;
    }
}

獲取方法

Method findMethod(Classclazz,Stringname),在類中查找指定名字方法

@Test
public void test7() throws IllegalAccessException, InstantiationException, InvocationTargetException {
    //查找類中的hello方法
    //這里要注意如果類中有方法名相同的重載方法時,一要要用下面的方法,把參數(shù)的類型給帶上
    //如果不是重載方法,用這個也沒問題
    Method say = ReflectionUtils.findMethod(Employee.class, "say");
    Employee employee = Employee.class.newInstance();
    employee.setRealName("zhangsan");
    say.invoke(employee, "lisi");
}

Method findMethod(Class clazz,Stringname, Class... paramTypes),有的時候同一個類可能會有多個方法名相同,形參數(shù)不同的重載方法,可以使用這個方法更精確的在類中找到指定方法;

@Test
public void test8() throws IllegalAccessException, InstantiationException, InvocationTargetException {
    Method hello = ReflectionUtils.findMethod(Employee.class, "hello",String.class,Boolean.class);
    Employee employee = Employee.class.newInstance();
    employee.setRealName("zhangsan");
    //執(zhí)行employee對象的hello方法
    Object msg = hello.invoke(employee, "lisi",true);
    System.out.println(msg);
}

Method[] getAllDeclaredMethods(Class leafClass),獲得類中所有方法,包括繼承而來的。

@Test
public void test9()  {
    //獲取類中所有的方法,包括繼承而來的
    Method[] methods = ReflectionUtils.getAllDeclaredMethods(Employee.class);
    for (Method o : methods) {
        System.out.println(o.getName());
    }
}

執(zhí)行方法

ObjectinvokeMethod(Method method,Objecttarget),執(zhí)行無參數(shù)的方法;

ObjectinvokeMethod(Method method,Objecttarget,Object... args),執(zhí)行有參數(shù)的方法

voidmakeAccessible(Method method),如果是私有方法,可以取消 Java 權(quán)限檢查,以便后續(xù)執(zhí)行該私有方法

@Test
public void test10() throws IllegalAccessException, InstantiationException, InvocationTargetException {
    //獲取set方法
    Method setRealName = ReflectionUtils.findMethod(Employee.class, "setRealName", String.class);
    //反射實例化一個對象
    Employee employee = Employee.class.newInstance();
    //放開權(quán)限檢查
    ReflectionUtils.makeAccessible(setRealName);
    //執(zhí)行set方法
    setRealName.invoke(employee, "zhangsan");
    //獲取get方法
    Method getRealName = ReflectionUtils.findMethod(Employee.class, "getRealName");
    //執(zhí)行g(shù)et方法
    Object result = getRealName.invoke(employee);
    Assert.isTrue(result.equals("zhangsan"), "getRealName方法執(zhí)行失敗");
}

到此這篇關(guān)于Springboot工具類ReflectionUtils使用教程的文章就介紹到這了,更多相關(guān)Springboot ReflectionUtils內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot項目中定時器的實現(xiàn)示例

    SpringBoot項目中定時器的實現(xiàn)示例

    在Spring?Boot項目中,你可以使用Spring框架提供的@Scheduled注解來編寫定時任務(wù),本文就來介紹一下SpringBoot項目中定時器的實現(xiàn),感興趣的可以了解一下
    2023-11-11
  • Java構(gòu)造方法和方法重載詳解

    Java構(gòu)造方法和方法重載詳解

    大家好,本篇文章主要講的是Java構(gòu)造方法和方法重載詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Springboot程序在使用Maven下載依賴時失效的解決方法

    Springboot程序在使用Maven下載依賴時失效的解決方法

    以前能成功創(chuàng)建SpringBoot項目并運行,但是現(xiàn)在再創(chuàng)建新項目時Maven下載依賴失敗,且maven依賴刷新按鍵一直沒反應(yīng),所以本文給大家介紹了Springboot程序在使用Maven下載依賴時失效的解決方法,需要的朋友可以參考下
    2024-05-05
  • spring注解@Service注解的使用解析

    spring注解@Service注解的使用解析

    這篇文章主要介紹了spring注解@Service注解的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 關(guān)于spring.factories失效原因分析及解決

    關(guān)于spring.factories失效原因分析及解決

    這篇文章主要介紹了關(guān)于spring.factories失效原因分析及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 使用Java WebSocket獲取客戶端IP地址的示例代碼

    使用Java WebSocket獲取客戶端IP地址的示例代碼

    在開發(fā)Web應(yīng)用程序時,我們通常需要獲取客戶端的 IP 地址用于日志記錄、身份驗證、限制訪問等操作,本文將介紹如何使用Java WebSocket API獲取客戶端IP地址,以及如何在常見的WebSocket框架中獲得客戶端 IP地址,需要的朋友可以參考下
    2023-11-11
  • Maven項目繼承實現(xiàn)過程圖解

    Maven項目繼承實現(xiàn)過程圖解

    這篇文章主要介紹了Maven項目繼承實現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • java學(xué)習(xí):日期的運算代碼

    java學(xué)習(xí):日期的運算代碼

    java.util.Date下的很多(構(gòu)造)方法,已經(jīng)被標(biāo)識為"過時"方法,官方推薦使用Calendar類來處理日期的運算,下面是示例:
    2013-02-02
  • 詳解Maven多模塊打包遇到的問題解決方法

    詳解Maven多模塊打包遇到的問題解決方法

    這篇文章主要介紹了詳解Maven多模塊打包遇到的問題解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Servlet中/和/*的區(qū)別詳解

    Servlet中/和/*的區(qū)別詳解

    本文將分析/和/*的區(qū)別這個老生常談的問題,但是很多時候看完就忘了,關(guān)于此問題這一篇文章就夠了,它將成為你的永久記憶,感興趣的可以了解一下
    2021-07-07

最新評論