JDK9之后限制了反射方式对于JDK内部类的访问,因此在使用高版本JDK运行较低版本的JDK时,某些依赖由于会发生错误。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class SimpleClass { private String foo = "foo"; public String getFoo() { return foo; } }
public class Main { public static class ReflectSimpleClass { private void changeFoo(SimpleClass simpleClass) { try { Field fooField = SimpleClass.class.getDeclaredField("foo"); fooField.setAccessible(true); fooField.set(simpleClass, "bar"); } catch (NoSuchFieldException | IllegalAccessException e) { System.out.println(e.getMessage()); } } } public static class ReflectInternalClass { private<T> void changeSize(ArrayList<T> arrayList) { try { Field sizeField = ArrayList.class.getDeclaredField("size"); sizeField.setAccessible(true); sizeField.set(arrayList, 114514); } catch (NoSuchFieldException | IllegalAccessException e) { System.out.println(e.getMessage()); } } } public static void main(String[] args) { SimpleClass simpleClass = new SimpleClass(); System.out.println(simpleClass.getFoo()); new ReflectSimpleClass().changeFoo(simpleClass); System.out.println(simpleClass.getFoo()); ArrayList<Integer> arrayList = new ArrayList(); System.out.println(arrayList.size()); new ReflectInternalClass().changeSize(arrayList); System.out.println(arrayList.size()); } }
|
解决方案
从 JDK 9 开始,引入了模块化系统(Project Jigsaw),限制了对 JDK 内部类的反射访问。为了在高版本 JDK 中通过反射访问 JDK 内部类,可以通过添加 JVM 参数来开放模块对所需方法的访问权限。
具体操作:
在 IntelliJ IDEA 中:
-
打开 Edit Configuration
。
-
在 VM options
中添加以下参数:
1
| --add-opens java.base/java.lang=ALL-UNNAMED
|
参数说明:
--add-opens
:用于开放模块的访问权限。
java.base/java.lang
:指定模块和包路径。
ALL-UNNAMED
:允许所有未命名模块访问。
__END__