繁体   English   中英

JDK 1.8 和 JDK 16 之间的反射差异

[英]Differences in reflection between JDK 1.8 and JDK 16

以下语句在 Oracle JDK1.8 和 OpenJDK 16 中均执行,但返回的结果不同。 在日常开发过程中建立,令人困惑的问题是差异是有意如此还是只是一个模糊的错误? 我已经完成了对类似问题的搜索,但没有找到预期的问题。

例子,

Field[] declaredFields = Field.class.getDeclaredFields();
// Field[12] with all private fields which are expected. (JDK 1.8)
// Empty field array. (JDK 16)

通过调试模式,关键语句位于:jdk.internal.reflect.Reflections中的第293、309行。 这些方法没有 javadoc。

// line 293
return (Field[])filter(fields, fieldFilterMap.get(containingClass));

// line 309
if (filteredNames.contains(WILDCARD)) {
    return (Member[]) Array.newInstance(memberType, 0);
}

这不是一个不起眼的错误,而是有意为之。

尽管filterFields()方法没有 JavaDoc 注释,但引用的fieldFilterMap字段具有 ( https://github.com/openjdk/jdk9/blob/master/jdk/src/java.base/share/classes/jdk/内部/反射/反射.java#L42 )

用于从公共视图中过滤掉某些类中敏感的字段和方法,或者它们可能包含 VM 内部对象。

由于引用的源代码来自 Java 9,它是有意引入的,与Java 16 源代码的比较表明,从那时起排除字段的数量有所增加。


有没有办法绕过这个限制? 我不这么认为。

根据问题跟踪器:改进对具有安全敏感字段的类的过滤

由核心反射维护的过滤器是一种有用的带状辅助,可避免将 Field 或 Method 对象泄漏给不受信任的代码。 可以改进过滤机制,从高度安全敏感的类中过滤掉所有字段例如 Class、ClassLoader 和一些 java.lang.reflect 类。

绕过此限制的所有方式都可能被视为安全问题,并将在下一个安全更新中关闭。


不幸的是,您没有说明为什么需要此访问权限。 您需要更改代码以不依赖对这些字段的访问。

另请注意,大多数字段都可以通过 getter 方法访问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM