Java 9 运行 代码如何使用未导出的包与 Java 8 编译

How is Java 9 running code compiled with Java 8 that is using a non-exported package

我使用 Java-8 编译器编译了以下代码:

package pack;
import sun.util.calendar.CalendarUtils;
public class A {
    public static void main(String[] args) {
        System.out.println(CalendarUtils.isGregorianLeapYear(2018));
    }
}

我使用 Java-8 编译器将上面的代码编译为:

gyan@gyan-pc:~/codes/java$ ~/Documents/softwares/Linux/jdk1.8.0_131/bin/javac -d . a.java
a.java:2: warning: CalendarUtils is internal proprietary API and may be removed in a future release
import sun.util.calendar.CalendarUtils;
                        ^
a.java:9: warning: CalendarUtils is internal proprietary API and may be removed in a future release
        System.out.println(CalendarUtils.isGregorianLeapYear(2018));
                           ^
2 warnings

我的默认版本 Java 解释器:

gyan@gyan-pc:~/codes/java$ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

我可以 运行 使用 Java-9 解释器编译的代码没有任何错误。

gyan@gyan-pc:~/codes/java$ java pack.a
false

据我所知:在 运行 时,包 "pack" 将包含在一个名为 "Unnamed module" 的特殊模块中。 "Unnamed module" 需要来自 Java 平台模块的所有模块。但是只有那个包可以被相应模块导出的"Unnamed module"使用。

我的问题是: 这里模块 java.base 没有导出包 "sun.util.calendar"。那"Unnamed module"是怎么用的呢?

正如 , the section Relaxed strong encapsulation 在这方面的陈述:-

--illegal-access=permit opens each package in each module in the run-time image to code in all unnamed modules, i.e., to code on the class path, if that package existed in JDK 8. This enables both static access, i.e., by compiled bytecode, and deep reflective access, via the platform's various reflection APIs.

The first reflective-access operation to any such package causes a warning to be issued, but no warnings are issued after that point. This single warning describes how to enable further warnings. This warning cannot be suppressed.

This mode is the default in JDK 9. It will be phased out in a future release and, eventually, removed.

此外,如果您尝试使用

执行编译后的代码
.../jdk-9.0.1.jdk/Contents/Home/bin/java --illegal-access=deny pack.Some

使用未来的默认值标志,您将无法使用以下跟踪按预期执行代码:

Exception in thread "main" java.lang.IllegalAccessError: class
pack.Some (in unnamed module @0x1055e4af) cannot access class
sun.util.calendar.CalendarUtils (in module java.base) because module
java.base does not export sun.util.calendar to unnamed module
@0x1055e4af    at pack.Some.main(Some.java:7)