首页 > 解决方案 > 有没有办法使用 jdk.internal.access.SharedSecrets 从 java.util 包中访问包私有 String.isLatin1() ?

问题描述

我正在尝试访问String.isLatin1()声明为(从 JDK 14 开始)为

boolean isLatin1() {
    return COMPACT_STRINGS && coder == LATIN1;
}

我可以通过反射来做到这一点

Method isLatin1 = String.class.getDeclaredMethod("isLatin1");
isLatin1.setAccessible(true);
isLatin1.invoke(""); //true

但我想知道我是否可以这样做SharedSecrets

我试过了

SharedSecrets.getJavaLangAccess().getDeclaredPublicMethods(String.class, "isLatin1");

但由于显而易见的原因,它返回一个空列表。我也尝试过使用jdk.internal.access.JavaLangReflectAccessavailable from SharedSecredts,但它没有任何合适的方法。

标签: javaunsafe

解决方案


这是行不通的。共享秘密机制提供了一种方法来封装特定的私有方法。如果您查看源代码,您会看到有一个“访问”接口,它公开了一组固定的方法。包的共享机密接口java.lang公开了一些无需复制即可获取字符串内部字节数组的方法。但它没有提供一种可以满足您需求的方法。

此外,isLatin1()您尝试访问的方法private不是包私有的,因此无论如何它都不能公开......除非您更改它。

简而言之,SharedSecrets除非您准备修改 OpenJDK 源代码并构建自己的 JVM ,否则您不能使用它。将其作为实验进行可能是可以接受的,但有很多用于生产用途的危险信号。

使用反射。更实际的......模,您可能会为您的应用程序导致未来的可移植性问题。(考虑到自 Java 1.1 以来,内部表示String已经改变了 2 到 3 次。它可能会再次发生。)


推荐阅读