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:
- Kotlin: ¿Es aquí una forma inteligente de lanzar NotImplementedError para todos los methods de una class?
- ¿Cómo obtengo una KProperty1 de una KProperty0?
- ¿Cómo puedo get una reference a un object Kotlin por su nombre?
- Acceda al tipo de delegado de Kotlin sin una instancia
- Llamadas a function de logging usando reflexión en kotlin
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?
- Kotlin: comparar los valores de propiedad de diferentes objects objective con (fuera) reflexión
- ¿Cómo get un KType en Kotlin?
- ¿Cómo obtengo las funciones declaradas de una class Kotlin (KClass en M12)?
- Usar reflexión para pasar y modificar una primitiva sin usar matriz
- ¿Por qué == e iguales producen resultados diferentes?
- ¿Cómo puedo establecer una propiedad de un object complementario en Kotlin a través de la reflexión?
- Implementando una interfaz de kotlin en java
- Quiero detectar si una class JVM es una class Kotlin o no
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!
- Base de datos de habitaciones Singleton en SyncAdapter para activar LiveData
- ¿Cómo agregar un oyente Onclick en un RecyclerView en Android Studio con Kotlin?