gpt4 book ai didi

reflection - String.intern()在JDBC驱动程序中返回不同的值

转载 作者:行者123 更新时间:2023-12-02 12:48:26 26 4
gpt4 key购买 nike

当我尝试制作一个伪造的JDBC驱动程序来测试安全的类加载器时,我发现以下代码具有奇怪的行为:

val stringClass = java.lang.String::class.java
val intern = stringClass.getMethod("intern")
val pooledString = intern.invoke("Hello World") as String
val valueField = stringClass.getDeclaredField("value")
valueField.isAccessible = true
val pooledValue = valueField.get(pooledString) as ByteArray
println(
"""|----------------------------------------
| String: ${System.identityHashCode(stringClass)}
| Thread: ${Thread.currentThread()}
| Pooled: ${System.identityHashCode(pooledString)}
| Internal: ${System.identityHashCode(pooledValue)}
|----------------------------------------""".trimMargin()
)
for (index in pooledValue.indices) {
pooledValue[index] = 'X'.toByte()
}

从JDBC驱动程序的伴随对象运行以上代码可以得到以下效果:
String: 349885916
Thread: Thread[main,5,main]
Pooled: 718231523
Internal: 1349414238

但是在加载JDBC驱动程序之前(在程序的相同执行过程中)从测试类的方法运行相同的代码将得出以下结果:
String: 349885916
Thread: Thread[main,5,main]
Pooled: 1635756693
Internal: 504527234

我本以为在两种情况下获取字符串的内部版本都应该给出相同的字符串,但是似乎即使在程序的同一运行中,两个位置也会为String.intern提供不同的值,这与javadoc冲突其中说:

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.



这是可以预期的吗?如果是,为什么值会不同?

最佳答案

该引用很可能已被垃圾回收。契约(Contract)规定,如果两次获得相同的字符串并比较返回的字符串,它们将相等。但是,如果得到一个字符串,则释放引用(使合并的字符串可用于gc),然后再次获得类似的字符串,则不能保证仍将其合并。您将获得一个新的合并字符串,并且该字符串具有不同的identityHashCode。

保留对pooledString的引用,以使其无法被垃圾回收,然后看看会发生什么!

关于reflection - String.intern()在JDBC驱动程序中返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47381691/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com