有没有办法使用 jdk.internal.access.SharedSecrets 从 java.util 包访问包私有的 String.isLatin1() ?

Is there a way to access package-private String.isLatin1() from java.util package using jdk.internal.access.SharedSecrets?

我正在尝试访问 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");

但出于显而易见的原因,它 returns 是一个空列表。我也尝试使用 SharedSecredts 提供的 jdk.internal.access.JavaLangReflectAccess,但它没有任何合适的方法。

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

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

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

使用反射。它更实用......模数你冒着为你的应用程序带来未来可移植性问题的风险。 (考虑到 String 的内部表示 自 Java 1.1 以来 已经改变了 2 或 3 次。它可能会再次发生。)