module-info.java 里的 exports、opens、requires 分别管什么?这篇用三个真实模块,从编译期、运行时反射、命令行参数和 JDK 自己的封装四个层面逐项验证(ServiceLoader 的 provides/uses 见前面一篇,Module Layer 在后面)。
[other2 直接用 lib.friend] 编译失败:package lib.friend is not visible | (package lib.friend is declared in module lib, which does not export it to module other2) | 1 error [app 直接用未导出的 lib.internal] 编译失败:package lib.internal is not visible | (package lib.internal is declared in module lib, which does not export it) | 1 error
直接用导出的包 lib.pub.Pub → pub.hi 用 exports ... to app 导出给我的包 lib.friend.Friend → friend.hi 反射加载未导出的包里的类 lib.internal.Hidden 并 newInstance → IllegalAccessException: class app.Main (in module app) cannot access class lib.internal.Hidden (in module lib) because module lib does not export lib.internal to module app 反射对 lib.internal.Hidden 的 public 方法 hi() 调用 → IllegalAccessException: class app.Main (in module app) cannot access class lib.internal.Hidden (in module lib) because module lib does not export lib.internal to module app 对 opens 的包里的类,setAccessible 读私有字段 → opened-secret
other 模块反射创建 lib.friend.Friend → IllegalAccessException: class other.Main (in module other) cannot access class lib.friend.Friend (in module lib) because module lib does not export lib.friend to module other
反射加载未导出的包里的类 lib.internal.Hidden 并 newInstance → lib.internal.Hidden@728938a9 反射对 lib.internal.Hidden 的 public 方法 hi() 调用 → hidden.hi
String.class 的私有字段 value:setAccessible → InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @15db9742
jdk.internal.misc.Unsafe.getUnsafe() → IllegalAccessException: class Main cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @15db9742
sun.misc.Unsafe(jdk.unsupported 模块里 opens 的包)的 theUnsafe 可访问:true
加上 --add-opens java.base/java.lang=ALL-UNNAMED 之后第一行: String.value 可访问
java --list-modules:这个 JDK 一共有 69 个模块;其中 java.base 的描述:
java.base 无限制导出的包 54 个,限定导出(qualified exports … to …)的包 67 个