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

Java通過反射獲取方法參數(shù)名的方式小結(jié)

 更新時間:2025年02月11日 15:32:15   作者:李白的手機  
這篇文章主要為大家詳細(xì)介紹了Java如何通過反射獲取方法參數(shù)名的方式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

1、前言

一般當(dāng)我們用類似下面的反射去獲取方法參數(shù)名時得到的一般是 arg0、arg1, 參數(shù)名默認(rèn)會丟失, 導(dǎo)致無法獲取到真實的方法參數(shù)名,下面介紹如何通過其他方式解決。

    class A {
        void getUser(String userName, String userId){}
    }
    
    Method method = A.class.getMethod(String.class,String.class);
    Parameter[] parameters = method.getParameters();
    for (Parameter parameter : parameters) {
        String name = parameter.getName();
        System.out.println(name); // 得到的是arg0, arg1 而非 userName、userId
    }

2、解決方式

方式2.1: 添加編譯參數(shù)配置 -parameters

java默認(rèn)在編譯工程代碼為class文件時,會將方法參數(shù)名擦除,替換成arg0、arg1之類。但是我們可以在編譯時配置將參數(shù)名也一并編譯進(jìn)去,在maven中新增如下編譯插件配置

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <!-- 配置編譯時將方法參數(shù)名保留 -->
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>

對于較新的 maven 版本(>= 3.6.2), 也可以直接使用 parameters 配置項:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <parameters>true</parameters>
    </configuration>
</plugin>

添加-parameters的編譯參數(shù)后,可以看到我們編譯后的class文件是源碼的參數(shù)名,而非原來的arg0、arg1。 之后我們用原生的反射Parameter.getName() 就可以獲取到的方法參數(shù)的真實參數(shù)名了

注意: 該方式僅對JDK8及以上版本有效, 以前版本JDK沒有提供該保留機制

方式2.2: 使用Spring的內(nèi)部工具類 - ParameterNameDiscoverer

如果正好你的項目依賴了spring,則可以直接使用spring的內(nèi)部工具類ParameterNameDiscoverer去獲取到方法真實參數(shù)名。ParameterNameDiscoverer的實現(xiàn)類 主要包含 LocalVariableTableParameterNameDiscoverer、StandardReflectionParameterNameDiscoverer 。 下面介紹如何使用

1、StandardReflectionParameterNameDiscoverer的使用

該發(fā)現(xiàn)器需要與 方式2.1: 添加編譯參數(shù)配置 -parameters 一樣添加編譯配置, 因為底層也是直接用反射Parameter去獲取而已

  // 創(chuàng)建參數(shù)名發(fā)現(xiàn)器
  ParameterNameDiscoverer discoverer = new StandardReflectionParameterNameDiscoverer();

  Method method = A.class.getMethod(String.class,String.class);

  // 獲取方法真實參數(shù)名.  userName, userId
  String[] parameterNames = discoverer.getParameterNames(method);

2、LocalVariableTableParameterNameDiscoverer的使用

  // 創(chuàng)建參數(shù)名發(fā)現(xiàn)器
  ParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();

  Method method = A.class.getMethod(String.class,String.class);

  // 獲取方法真實參數(shù)名.  userName, userId
  String[] parameterNames = discoverer.getParameterNames(method);

該發(fā)現(xiàn)器底層原理是在編譯類時生成一個調(diào)試信息的局部變量表LocalVariableTable,然后基于ASM字節(jié)碼技術(shù)去解析LocalVariableTable得到參數(shù)名, 所以它也需要在編譯時額外添加 編譯配置, 請在maven中添加如下-g的編譯參數(shù)配置

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerArgs>
                        <!-- 生成局部變量表 -->
                        <arg>-g:vars</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

該方法優(yōu)點是JDK8以下版本也能使用,但是缺點是無法獲取到接口的方法參數(shù)名

3、DefaultParameterNameDiscoverer的使用

  // 創(chuàng)建參數(shù)名發(fā)現(xiàn)器
  ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();

  Method method = A.class.getMethod(String.class,String.class);

  // 獲取方法真實參數(shù)名.  userName, userId
  String[] parameterNames = discoverer.getParameterNames(method);

這個參數(shù)名發(fā)現(xiàn)器是一個組合模式的發(fā)現(xiàn)器, 本身不去實現(xiàn)獲取參數(shù)名的邏輯,而是組合其他參數(shù)名發(fā)現(xiàn)器, 然后迭代調(diào)用每個參數(shù)名發(fā)現(xiàn)器直到找到真實參數(shù)名。 從下面源碼來看 主要內(nèi)置了前面講到的兩種StandardReflectionParameterNameDiscoverer 和 LocalVariableTableParameterNameDiscoverer。 所以如果要讓對應(yīng)的參數(shù)名發(fā)現(xiàn)器生效,需要配合對應(yīng)發(fā)現(xiàn)器的使用邏輯 否則一樣無法獲取到方法參數(shù)名。

// 源碼
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {

	public DefaultParameterNameDiscoverer() {
		if (!GraalDetector.inImageCode()) {
			if (KotlinDetector.isKotlinReflectPresent()) {
				addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
			}
			addDiscoverer(new StandardReflectionParameterNameDiscoverer()); // 依賴編譯參數(shù) -parameters
			addDiscoverer(new LocalVariableTableParameterNameDiscoverer()); //  // 依賴編譯參數(shù) -g
		}
	}

}

使用總結(jié)

1、參數(shù)名獲取的本質(zhì)

  • 所有方案都依賴編譯時保留參數(shù)名信息(通過-parameters或-g參數(shù)), 所以編譯的時候有就是有,沒有就是沒有,尤其是一些第三方依賴的類
  • 如果是第三方依賴的類若未攜帶調(diào)試信息(如未使用上述編譯參數(shù)進(jìn)行編譯),則無論如何也是無法獲取真實參數(shù)名, 除非第三方庫已使用-parameters編譯,仍可通過反射獲?。ǖ珜嶋H場景較少見)

2、版本適配建議

  • JDK8+項目: 優(yōu)先使用-parameters編譯參數(shù)(性能最佳), 配合StandardReflectionParameterNameDiscoverer
  • JDK7及以下: 使用-g編譯參數(shù), 配合LocalVariableTableParameterNameDiscoverer
  • Spring項目: 推薦使用DefaultParameterNameDiscoverer(自動適配最優(yōu)策略), 可同時配置兩種編譯參數(shù)提升兼容性:

3、在一些springBoot 2.0以后版本中spring-boot-starter-parent會內(nèi)置了編譯參數(shù)配置,所以不用配也可以直接使用ParameterNameDiscoverer, 當(dāng)然需要確保項目是否覆蓋了默認(rèn)配置導(dǎo)致失效,需要重新配

知名應(yīng)用場景舉例

  • spring-mvc 的 @RequestParam 參數(shù)名的可省略配置
  • mybatis 的 @Param 也可以不用配置

到此這篇關(guān)于Java通過反射獲取方法參數(shù)名的方式小結(jié)的文章就介紹到這了,更多相關(guān)Java反射獲取方法參數(shù)名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java數(shù)組的定義和聲明方法

    詳解Java數(shù)組的定義和聲明方法

    在Java開發(fā)中,數(shù)組是最常用的數(shù)據(jù)結(jié)構(gòu)之一,因此,深入了解Java數(shù)組的定義和聲明是非常必要的,本文將詳細(xì)介紹Java數(shù)組的定義和聲明方法,以及其在實際開發(fā)中的應(yīng)用場景、優(yōu)缺點等方面,需要的朋友可以參考下
    2023-11-11
  • Java中l(wèi)ist.contains()的用法及拓展

    Java中l(wèi)ist.contains()的用法及拓展

    List集合相信大家在開發(fā)過程中幾乎都會用到,有時候難免會遇到集合里的數(shù)據(jù)是重復(fù)的,需要進(jìn)行去除,下面這篇文章主要給大家介紹了關(guān)于Java中l(wèi)ist.contains()的用法及拓展的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • SpringCloud降級規(guī)則使用介紹

    SpringCloud降級規(guī)則使用介紹

    這篇文章主要介紹了SpringCloud降級規(guī)則,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)

    Java數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)

    下面小編就為大家?guī)硪黄狫ava數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • spring task @Scheduled注解各參數(shù)的用法

    spring task @Scheduled注解各參數(shù)的用法

    這篇文章主要介紹了spring task @Scheduled注解各參數(shù)的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • idea中報錯不支持發(fā)行版本問題及解決

    idea中報錯不支持發(fā)行版本問題及解決

    在使用Spring框架進(jìn)行項目開發(fā)時,有時會遇到因JDK版本不一致導(dǎo)致的項目運行錯誤,解決此問題的方法主要有兩步:首先,確保項目的Project和Modules設(shè)置中的JDK版本一致;其次,在IDE的Settings中找到Java?Compiler
    2024-11-11
  • springboot2.3 整合mybatis-plus 高級功能及用法詳解

    springboot2.3 整合mybatis-plus 高級功能及用法詳解

    這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級功能,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot容器的主要組件詳解

    SpringBoot容器的主要組件詳解

    這篇文章主要介紹了SpringBoot容器的主要組件詳解,SpringBoot?是基于?Spring?Framework?的一種快速開發(fā)框架,它可以幫助開發(fā)者快速地構(gòu)建獨立的、生產(chǎn)級別的、可部署的應(yīng)用程序,需要的朋友可以參考下
    2023-09-09
  • java集合Collection常用方法解讀

    java集合Collection常用方法解讀

    這篇文章主要介紹了java集合Collection常用方法解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java基于Luhn算法實現(xiàn)銀行卡卡號格式校驗詳解

    Java基于Luhn算法實現(xiàn)銀行卡卡號格式校驗詳解

    在金融行業(yè),特別是涉及到銀行卡處理的場景中,確保銀行卡號的有效性是至關(guān)重要的,本文將詳細(xì)介紹如何使用Java實現(xiàn)基于Luhn算法的銀行卡卡號格式校驗,有需要的可以了解下
    2026-01-01

最新評論

广南县| 铜鼓县| 清河县| 西林县| 苍梧县| 茌平县| 宝清县| 苏尼特右旗| 乐安县| 本溪市| 乳源| 湾仔区| 凤庆县| 茌平县| 镶黄旗| 疏勒县| 甘孜县| 文化| 沁阳市| 玉屏| 即墨市| 云南省| 峡江县| 阳泉市| 包头市| 嘉善县| 乐安县| 武义县| 紫阳县| 治多县| 伊宁市| 壶关县| 凯里市| 简阳市| 灌云县| 贵溪市| 磐石市| 杂多县| 民乐县| 赤水市| 塔河县|