提问人:Joe 提问时间:11/16/2023 更新时间:11/16/2023 访问量:29
将 java.lang.reflect 字段的可访问性设置为 true 有任何问题吗?
Any issue in setting the accessiblilty of java.lang.reflect Field to true?
问:
我正在尝试编写一个通用函数来打印任何对象的各个字段。我正在使用 java.lang.reflect.Field 来获取 onject 中的各个字段。但是,仅当我将该字段的可访问属性设置为 true 时,代码才有效,如下面的代码中突出显示的那样。我唯一担心的是,这会导致我使用该对象的其他任何地方出现任何问题吗?
Field[] fields = MyClass.class.getDeclaredFields();
for(Field field : fields) {
try {
field.setAccessible(true); // Would this lead to any issue anywhere else?
Object obj = field.get(m); // m is a sample object of MyClass
System.out.println("Object: " + obj);
} catch (Exception e) {
System.out.println("Illegal Access Exception : " + e);
}
}
答:
4赞
rzwitserloot
11/16/2023
#1
是的,这意味着您的代码将无法在 JVM21 及更高版本上运行的任何模块化(如,特定类型的模块化)系统上运行。module-info.java
如果模块 A 没有向模块 B 公开某些元素(通常是因为它根本没有导出它,可能是因为 A 只将其导出到显式枚举的模块列表),那么它就不起作用,并且在启动时不会缺少开关。.setAccessible
--add-opens
java
更一般地说,“打印对象的所有字段”违反了你不应该违反的封装规则——java 不是那种语言。如果要“打印对象”,则类定义(包含表示该类的定义的源文件)需要有一个执行此操作的方法。如果它没有该方法,则必须编辑该源文件才能添加它,如果不能这样做,则必须忍受它。.java
public class Foo
如果目的是专门进行调试,那么最好使用调试器基础结构(JVMTI - 您可以在 Web 上搜索它,或者作为代理加载,“java 代理”也可以搜索教程)。为此,您需要完全不同的代码,通常不会在代理中使用反射。
评论
0赞
VGR
11/17/2023
事实上,我很确定这种反射不适用于任何支持模块(9 及更高版本)的 Java 版本中的模块。
评论
setAccessible(true)
Field
Field