String.intern () devuelve diferentes valores en un controller JDBC

Mientras intentaba hacer un controller JDBC falso para probar un cargador de classs seguro, encontré un comportamiento extraño con el siguiente código:

val stringClass = java.lang.String::class.java val intern = stringClass.getMethod("intern") val pooledString = intern.invoke("Hello World") as String val valueField = stringClass.getDeclanetworkingField("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() } 

Ejecutar el código anterior desde un object complementario del controller JDBC da esto:

 String: 349885916 Thread: Thread[main,5,main] Pooled: 718231523 Internal: 1349414238 

pero ejecutar el mismo código de un método de la class de testing antes de cargar el controller JDBC (durante la misma ejecución del progtwig) da esto:

 String: 349885916 Thread: Thread[main,5,main] Pooled: 1635756693 Internal: 504527234 

Hubiera pensado que get la versión interna de la cadena debería haber dado la misma cadena en ambos casos, pero parece que incluso dentro de la misma ejecución del progtwig, las 2 ubicaciones dan diferentes valores para String.intern, lo que entra en conflicto con el javadoc. que dice:

Cuando se invoca el método interno, si el grupo ya contiene una cadena igual a este object String según lo determinado por el método equals (Object) , se devuelve la cadena del grupo. De lo contrario, este object String se agrega al grupo y se devuelve una reference a este object String .

¿Es esto esperado, y si es así, por qué los valores son diferentes?

Lo más probable es que la reference haya sido recogida de basura. El contrato dice que si obtiene la misma cadena dos veces y compara las cadenas devueltas, serán iguales. Sin embargo, si obtienes una cadena, libera la reference (haciendo que la cadena agrupada esté disponible para gc) y luego vuelvas a get una cadena similar, nada garantiza que aún se agrupe. Obtendrá una nueva cadena agrupada en su lugar y que tiene un identificadorHashCode diferente.

¡Mantenga una reference a pooledString para que no se pueda recolectar basura y vea qué sucede!

  • ¿Cómo establecer el valor de propiedad delegada por reflexión en kotlin?
  • ¿Hay alguna manera de identificar una class de datos Kotlin de una class regular de Kotlin?
  • java.lang.IllegalArgumentException: Callable espera 4 arguments, pero se proporcionaron 3
  • ¿Por qué == e iguales producen resultados diferentes?
  • Crear una nueva instancia de una KClass
  • Kotlin: isAssignableFrom y reflexiones del tipo de reflexión
  • Obtén la function por nombre dinámicamente en Kotlin
  • instancia :: class.java vs. instance.javaClass
  • Reflexión de Kotlin: compruebe si la propiedad tiene tipo
  • Kotlin language obtiene class en time de ejecución
  • ¿Cómo hacer inferencia tipo Kotlin desde la reflexión KClass?