janvladimirmostert
02/27/2024, 8:05 AMT::class.hashCode
where T is an interface (or abstract class) that I control?
interface Foo {
}
inline fun <reified T : Foo> decode(byteArray: ByteArray) {
println(T::class.hashCode())
println(T::class.java.hashCode())
}
class INT4 : Foo {
companion object : Foo
}
Sam
02/27/2024, 8:36 AMClass
or KClass
is just the Java class's identity hash code, which is probably based on its location in memory.Sam
02/27/2024, 8:36 AMjanvladimirmostert
02/27/2024, 9:27 AMSam
02/27/2024, 10:22 AMSam
02/27/2024, 10:23 AMClassValue
, which is the canonical Java way to store a mapping between a class and a value, and should be pretty fast and efficient.Sam
02/27/2024, 10:28 AMdecode(INT4, someEncodedByteArray)
instead of decode<INT4>(someEncodedByteArray)
.Sam
02/27/2024, 10:30 AMDecodable
interface itselfjanvladimirmostert
02/27/2024, 12:02 PMobject Mapper : ClassValue<Int>() {
override fun computeValue(type: Class<*>?): Int {
TODO("lookup type somehow")
}
}
inline fun <reified T : Foo> decode(byteArray: ByteArray) {
println(Mapper.get(T::class.java))
}
janvladimirmostert
02/27/2024, 12:22 PMjanvladimirmostert
02/27/2024, 12:45 PMinterface Enc {}
interface Dec {
val code: Int
}
object Mapper : ClassValue<Int>() {
private val mappings = listOf(INT4, FLOAT)
override fun computeValue(type: Class<*>?): Int {
println("computing value for $type")
for (mapping in mappings) {
val matches = (mapping::class.qualifiedName?.startsWith(type?.canonicalName ?: "?")) == true
if (matches) {
return mapping.code
}
}
return -1
}
}
inline fun <reified T : Enc> decode(byteArray: ByteArray) {
println(Mapper.get(T::class.java))
}
class INT4 : Enc {
companion object : Dec {
override val code: Int
get() = 1
}
}
class FLOAT : Enc {
companion object : Dec {
override val code: Int
get() = 2
}
}
fun main() {
decode<INT4>(byteArrayOf()) // computeValue called
decode<INT4>(byteArrayOf())
decode<INT4>(byteArrayOf())
decode<INT4>(byteArrayOf())
decode<INT4>(byteArrayOf())
decode<FLOAT>(byteArrayOf()) // computeValue called
}
I'll mess a around a bit more, but this is decent, that compute is only called once which is perfect