[英]What is the use of limitmods flag and listmods in jdk9/java-9?
[英]How to use sun.reflect package in jdk9/java-9?
我正在使用jdk-9,我想在我的代碼中使用sun.reflect.*
包但我得到以下異常
Exception in thread 'main' java.lang.IllegalAccessError : class Test (in moudle: Unnamed Module) cannot access class sun.reflect.Reflaction (in module:java.base), sun.reflect is not exported to Unnamed module
當我使用JDK-9運行下面的示例代碼時
public static void main(String args[]){
System.out.println(Reflection.getCallerClass(3));
}
適用於較新的OpenJDK 9 EA版本。 例如:
$ java -version
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+138)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+138, mixed mode)
$ javac Test.java
Test.java:5: warning: Reflection is internal proprietary API and may be removed in a future release
System.out.println(Reflection.getCallerClass(3));
^
Note: Test.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 warning
$ java Test
null
似乎它是作為JDK-8137058的一部分在9-ea + 115版本中修復的 。 所以你可能正在使用舊的EA版本。 一般來說,@ Holger是對的:這個API很有可能在將來的Java版本中完全消失,因此請考慮遷移到StackWalker API。
這些sun.*
包從來都不是官方API的一部分,並且不能保證存在,即使在Java 9之前的JVM中也是如此。為將來完全消失做好准備,甚至不能通過某些選項恢復。 值得慶幸的是,有一個官方API涵蓋了這個功能,消除了對非官方API的需求。
Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) .getCallerClass();
獲取堆棧中的第n個調用者(例如,第三個,如您的示例中所示):
Class<?> c = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk(s -> s.map(StackWalker.StackFrame::getDeclaringClass).skip(3).findFirst().orElse(null));
java -cp classes -XaddExports:java.base/sun.reflect Test
Jigsaw(java-9)具有模塊化概念,他們為compact-1設計了java.base包,它們封裝了sun.reflect.*
。 所以sun.reflect.*
無法在外面訪問。 由於這個原因,它給出了例外
Exception in thread 'main' java.lang.IllegalAccessError : class Test (in moudle: Unnamed Module) cannot access class sun.reflect.Reflaction (in module:java.base), sun.reflect is not exported to Unnamed module
為了提供向后兼容性,他們提供了使用該包的方式,如下所示。
java -cp classes -XaddExports:java.base/sun.reflect Test
使用遷移文檔中提到的最新版本和更改來更新線程。 盡管如此,@ Holger正確地指出了這一點。
在JDK 9中仍可訪問的sun.reflect
包中的API包括:
sun.reflect.Reflection::getCallerClass(int)
相反,使用stack-walking API,請參閱JEP 259:Stack-Walking API。sun.reflect.ReflectionFactory.newConstructorForSerialization
默認情況下,這些API在運行時可訪問。 它們已被移動到jdk.unsupported
模塊,該模塊存在於JRE和JDK映像中。 需要這些API的模塊必須聲明對jdk.unsupported
模塊的依賴性。
sun.misc和sun.reflect包中的其余內部API已被移動,因為它們不應該被訪問。 如果需要使用其中一個內部API,可以使用--add-exports
命令行選項中斷封裝。 (類似於@NIrav的回答 )。 盡管如文檔中所述, 此選項僅應用作遷移的臨時輔助工具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.