java9 opens与exports的区别
為什么80%的碼農都做不了架構師?>>> ??
序
本文主要研究下java9 opens與exports的區別
open及exports
open
- open module
主要用于解決deep reflection問題,open的作用是表示該模塊下的所有的包在runtime都允許deep reflection(包括public及private類型) 但是編譯時期,僅僅允許該module中聲明過exports的包可以訪問,如果沒有exports則該包的類在編譯時期不可讀
- opens package
用于聲明該模塊的指定包在runtime允許使用反射訪問
exports
表示允許在編譯時和運行時訪問指定包的public成員
open及exports對反射的影響
反射方法
- 目標類
- 訪問類名反射
- 通過包名反射
沒有exports,也沒有opens
- module-info.java
這里沒有exports及opens com.packt.lib.sub1
- 通過類名反射(編譯報錯)
- 通過包名反射(newInstance運行時報錯)
沒有exports,有opens
- module-info.java
- 通過類名反射
由于沒有exports,則編譯不過
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.2:compile (default-compile) on project main: Compilation failure [ERROR] /Users/demo/java9-multi-module-demo/main/src/main/java/com/packt/App.java:[30,41] 程序包 com.packt.lib.sub1 不可見 [ERROR] (程序包 com.packt.lib.sub1 已在模塊 packt.lib 中聲明, 但該模塊未導出它)- 通過包名反射
像上面那種直接引用包名來反射的,不會報錯,因為編譯可以通過,運行正常
有exports,沒有opens
module packt.lib {exports com.packt.lib;exports com.packt.lib.sub1; }- 通過類名反射
可以編譯通過,運行報錯
Sub1Service being instanced Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make private void com.packt.lib.sub1.Sub1Service.privateMethod() accessible: module packt.lib does not "opens com.packt.lib.sub1" to module packt.mainat java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)at packt.main/com.packt.App.main(App.java:44) [ERROR] Command execution failed.- 通過包名反射
可以編譯通過,運行報錯
Sub1Service being instanced [Ljava.lang.reflect.Method;@4157f54e public method called! Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make protected void com.packt.lib.sub1.Sub1Service.protectedMethod() accessible: module packt.lib does not "opens com.packt.lib.sub1" to module packt.mainat java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)at packt.main/com.packt.App.main(App.java:34) [ERROR] Command execution failed.直接open整個module,但是沒有exports
- module-info.java
- 直接訪問類反射
這種情況,如果是直接訪問該類來使用反射,由于沒有exports該package,則直接編譯報錯
- 通過包名反射
這種情況編譯可以通過,運行正常
直接open整個module,也有exports
open module packt.lib {exports com.packt.lib;exports com.packt.lib.sub1; }兩種訪問方式的反射均正常編譯及運行。
小結
- open表示允許運行時通過反射使用
open的作用是表示該模塊下的所有的包在runtime都允許deep reflection(包括public及private類型);opens package的作用只是允許該包在runtime都允許deep reflection
open及opens都僅僅是開放runtime時期的可以通過反射訪問(蘊含了運行時的exports)。
- exports表示允許訪問指定包的public成員(編譯及運行時)
如果反射不直接通過類名調用,只是運行時通過包名使用,則只需open或opens即可 如果是通過類名來反射,由于用到了該類,需要通過exports指定可以訪問,不指定則編譯期立即報錯 如果是通過類名來反射使用public方法或newInstance,如果沒有exports,則運行時報錯 如果有exports,但是沒有open,因此編譯通過運行時報錯
- illegal-access
--illegal-access默認是permit,表示允許unnamed modules反射(java.lang.reflect/java.lang.invoke)使用所有named modules中的類
doc
- Java 9 揭秘(2. 模塊化系統)
轉載于:https://my.oschina.net/go4it/blog/1625318
總結
以上是生活随笔為你收集整理的java9 opens与exports的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab 数字图像处理1---图像的
- 下一篇: ES6+mocha+istanbul,针