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

淺談MyBatis-Plus 提示發(fā)生了非法的反射訪問(wèn)操作

 更新時(shí)間:2026年01月25日 14:34:28   作者:一線大碼  
本文主要介紹了MyBatis-Plus 提示發(fā)生了非法的反射訪問(wèn)操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

最近使用 MyBatis-Plus 框架,在執(zhí)行 SQL 查詢的時(shí)候控制臺(tái)日志提示了該警告信息(An illegal reflective access operation has occurred),并且只有首次執(zhí)行的時(shí)候才提示,同樣的方法再次調(diào)用則不會(huì)提示,我用的 JDK11。下面轉(zhuǎn)載一篇文章,解決了這個(gè)問(wèn)題。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.baomidou.mybatisplus.core.toolkit.SetAccessibleAction (file:/C:/Users/wangbo.GTCOM/.m2/repository/com/baomidou/mybatis-plus-core/3.4.3.4/mybatis-plus-core-3.4.3.4.jar) to field java.lang.invoke.SerializedLambda.capturingClass
WARNING: Please consider reporting this to the maintainers of com.baomidou.mybatisplus.core.toolkit.SetAccessibleAction
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

反射是一項(xiàng)相當(dāng)強(qiáng)大的特性,不僅在各類框架中被廣泛應(yīng)用,即使是在日常開(kāi)發(fā)中我們也隔三差五得要和它打交道。然而在 JDK9 中 JDK 對(duì)反射加上了一些限制,需要注意。

考慮有如下的代碼:

import java.lang.reflect.Field;
import java.util.ArrayList;

public class TestReflect {

    public static int getCapacity(ArrayList<?> l) throws Exception {
        Field dataField = l.getClass().getDeclaredField("elementData");
        // 即使設(shè)置了可訪問(wèn)也會(huì)觸發(fā)警告
        dataField.setAccessible(true);
        // 注意這行
        return ((Object[]) dataField.get(l)).length;
    }

    public static void main(String[] args) {
        var arr = new ArrayList<Integer>(4);
        try {
            System.out.println("capacity:" + TestReflect.getCapacity(arr));        
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

這段代碼的作用是讀取 ArrayList 的實(shí)際容量,由于 JDK 并沒(méi)有為我們提供類似 cap() 這樣的公開(kāi)接口,所以我們不得不使用反射來(lái)繞過(guò)限制。

在 JDK8 上這段代碼運(yùn)行良好,然而當(dāng)我們升級(jí)成 JDK9 后卻會(huì)是這樣的一幅畫面:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by TestReflect (file:/tmp/TestReflect.java) to field java.util.ArrayList.elementData
WARNING: Please consider reporting this to the maintainers of TestReflect
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
capacity:4

別緊張,代碼還是正常運(yùn)行了。其實(shí)這是 JDK9 中添加的新特性,即 reflect 不再可以訪問(wèn) non-public 成員以及不可公開(kāi)訪問(wèn)的 class,原先這些訪問(wèn)控制雖然存在但是可以通過(guò) reflect 繞過(guò),從 JDK9 開(kāi)始反射也將遵循訪問(wèn)控制的規(guī)則。JDK9 中對(duì)于第一次訪問(wèn)非公開(kāi)成員的操作會(huì)顯示警告信息,我們可以通過(guò)使用--illegal-access=warn選項(xiàng)進(jìn)一步顯示出有用的 warning 提示:

$ java --illegal-access=warn TestReflect.java

WARNING: Illegal reflective access by TestReflect (file:/tmp/TestReflect.java) to field java.util.ArrayList.elementData
capacity:4

將 warn 替換為 debug 可以指出非法訪問(wèn)發(fā)生在哪一行(通過(guò)觀察打印的調(diào)用堆棧),而替換為 deny 則將會(huì)直接拋出java.lang.reflect.InaccessibleObjectException異常:

$ java --illegal-access=deny TestReflect.java

java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.lang.Object[] java.util.ArrayList.elementData accessible: module java.base does not "opens java.util" to unnamed module @72967906
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:349)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:289)
        at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:174)
        at java.base/java.lang.reflect.Field.setAccessible(Field.java:168)
        at TestReflect.getCapacity(TestReflect.java:7)
        at TestReflect.main(TestReflect.java:14)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:415)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)

對(duì)于后續(xù)的更新版本,JDK 會(huì)將 deny 作為默認(rèn)的行為,不過(guò)目前(14.0.2)默認(rèn)行為依舊為 permit(顯示那些默認(rèn)的 warning 信息)。

顯而易見(jiàn),新特性會(huì)導(dǎo)致如下的結(jié)果:

  1. 無(wú)法再通過(guò)反射修改/訪問(wèn)其他類型的私有成員;
  2. 無(wú)法再通過(guò)反射使用 internal APIs。

然而健康的代碼并不應(yīng)該依賴于非法的訪問(wèn):

  1. 標(biāo)記為非公開(kāi)的成員本身就不希望被外部直接訪問(wèn),訪問(wèn)應(yīng)該通過(guò) public APIs 進(jìn)行;
  2. 無(wú)視訪問(wèn)控制會(huì)導(dǎo)致數(shù)據(jù)的修改變得不可控,從而產(chǎn)生意想不到的缺陷;
  3. 私有成員可能會(huì)隨著開(kāi)發(fā) / 更新 / 修復(fù) / 重構(gòu)等活動(dòng)而改變,過(guò)度依賴于訪問(wèn)其他 class 的私有成員會(huì)產(chǎn)生高耦合性的代碼,使維護(hù)的負(fù)擔(dān)成倍增加。

當(dāng)然,想要消除警告也很容易,雖然官方文檔中不建議無(wú)視或消除這個(gè)警告:

$ java --add-opens java.base/java.util=ALL-UNNAMED TestReflect.java

capacity:4

--add-opens選項(xiàng)將特定的 module 下的 package 公開(kāi)給指定的 package,或者使用特殊值 ALL-UNAMED 代指所有匿名包(比如本例中的類),公開(kāi)后我們就可以通過(guò) reflect 來(lái)訪問(wèn)被公開(kāi)包中 class 的成員而不拋出異常了(需要使用 setAccessible(true))。

這種 trick 實(shí)際上嚴(yán)重破壞了代碼的封裝,個(gè)人是極不推薦的;此外還可以選擇將 JDK 版本鎖定在 8,當(dāng)然這也是不得以才為之的辦法,那么對(duì)于即想嘗試新版本又不想被警告信息煩擾的話該怎么辦呢,只能嘗試下面幾種辦法了:

  1. 如果是第三方依賴導(dǎo)致的警告,升級(jí)對(duì)應(yīng)的依賴或是聯(lián)系該依賴的維護(hù)人員,請(qǐng)他們盡快修復(fù)問(wèn)題。通常來(lái)說(shuō)這類向后兼容的問(wèn)題修復(fù)無(wú)需花費(fèi)很多的時(shí)間。
  2. 如果是自己的代碼,則考慮是否要對(duì)私有成員提供可訪問(wèn)的 public API,是否將私有成員公有化。
  3. 如果使用了某些 internal apis,那么你的代碼應(yīng)該重構(gòu)以避免過(guò)度依賴這些 api。

到此這篇關(guān)于淺談MyBatis-Plus 提示發(fā)生了非法的反射訪問(wèn)操作的文章就介紹到這了,更多相關(guān)MyBatis-Plus 非法的反射訪問(wèn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)案例及驗(yàn)證

    Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)案例及驗(yàn)證

    微服務(wù)架構(gòu)是一項(xiàng)在云中部署應(yīng)用和服務(wù)的新技術(shù),這篇文章主要介紹了Java微服務(wù)無(wú)損發(fā)布生產(chǎn)實(shí)戰(zhàn)及驗(yàn)證的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • SpringSecurity表單配置之登錄成功及頁(yè)面跳轉(zhuǎn)原理解析

    SpringSecurity表單配置之登錄成功及頁(yè)面跳轉(zhuǎn)原理解析

    這篇文章主要介紹了SpringSecurity表單配置之登錄成功及頁(yè)面跳轉(zhuǎn)原理解析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • 基于Java字符編碼的使用詳解

    基于Java字符編碼的使用詳解

    本篇文章對(duì)Java字符編碼的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • datax-web在windows環(huán)境idea中模塊化打包部署操作步驟

    datax-web在windows環(huán)境idea中模塊化打包部署操作步驟

    這篇文章主要介紹了datax-web在windows環(huán)境idea中模塊化打包部署操作步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • intellij idea使用git stash暫存一次提交的操作

    intellij idea使用git stash暫存一次提交的操作

    這篇文章主要介紹了intellij idea使用git stash暫存一次提交的操作,具有很好的參考價(jià)值希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • 詳解Java中ArrayList類

    詳解Java中ArrayList類

    這篇文章主要介紹了Java中ArrayList類,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • spring中@ControllerAdvice 注解的使用

    spring中@ControllerAdvice 注解的使用

    @ControllerAdvice注解是Spring3.2中新增的注解,主要用于Controller的全局配置,本文就來(lái)介紹一下spring中@ControllerAdvice 注解的使用,感興趣的可以了解一下
    2024-09-09
  • Spring?MVC?URL地址映射的示例代碼

    Spring?MVC?URL地址映射的示例代碼

    @RequestMapping是一個(gè)用來(lái)處理請(qǐng)求地址映射的注解,可用于類或方法上。用于類上,表示類中的所有響應(yīng)請(qǐng)求的方法都是以該地址作為父路徑。,這篇文章主要介紹了Spring?MVC?URL地址映射,需要的朋友可以參考下
    2022-07-07
  • Java一鍵獲取(CPU、內(nèi)存、硬盤、操作系統(tǒng))系統(tǒng)信息

    Java一鍵獲取(CPU、內(nèi)存、硬盤、操作系統(tǒng))系統(tǒng)信息

    這篇文章主要為大家詳細(xì)介紹了如何使用Java一鍵獲取CPU、內(nèi)存、硬盤、操作系統(tǒng)等系統(tǒng)信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-03-03
  • Java使用java -jar啟動(dòng)并按日分包日志的最佳實(shí)踐

    Java使用java -jar啟動(dòng)并按日分包日志的最佳實(shí)踐

    在生產(chǎn)環(huán)境中,Java應(yīng)用程序通常以java -jar方式運(yùn)行,而日志管理是運(yùn)維的重要部分,如果日志文件過(guò)大,不僅影響性能,還會(huì)增加排查問(wèn)題的難度,因此,按日分包日志成為常見(jiàn)的需求,本文將介紹4種實(shí)現(xiàn)方式,并提供詳細(xì)配置和代碼示例,需要的朋友可以參考下
    2025-07-07

最新評(píng)論

普宁市| 武功县| 寿宁县| 吉林市| 岳西县| 嘉兴市| 兴业县| 山丹县| 黄龙县| 青阳县| 鸡西市| 石楼县| 革吉县| 溆浦县| 浦县| 阜南县| 海门市| 大港区| 洛隆县| 洱源县| 万源市| 余姚市| 霍邱县| 甘德县| 巫山县| 河津市| 蒲城县| 黑龙江省| 芒康县| 鹤岗市| 名山县| 杭锦旗| 宜都市| 铁力市| 上林县| 平利县| 罗田县| 文水县| 开化县| 正阳县| 平安县|