I have a pretty short question about an extension function that would help clear some of my code. Basically I have some transformations on the hashCode of a class name and I want an extension function to do the transformations.
Example:
Getting the name hashCode: StateA::class.java.name.hashCode()
where StateA is a simple class.
I want to the extension function like:
fun Class<*>.transformName(): String {
var hashString = this.javaClass.name.hashCode()
//Do my stuff on that hashString
return hashString
}
But this doesn't seem to work. When I apply the extension function with StateA.transformName()
, the function gives me an error with Unresolved Reference.
I tried various things like applying the function to StateA::class
or having the hashString equal to this::class.java.name.hashCode()
but nothing works. Any tips?
This is done via special declarations called extensions. For example, you can write new functions for a class or an interface from a third-party library that you can't modify. Such functions can be called in the usual way, as if they were methods of the original class. This mechanism is called an extension function.
Are you using Intellij IDEA or Android Studio? Open a Kotlin file that has extension functions, go to Tools -> Kotlin -> Show bytecode, and from the bytecode window that pops up choose Decompile. You'll see what the Java analog of that code looks like and it'll quickly become apparent what the trick is!
You can't really achieve the StateA.transformName()
syntax, as StateA
just on its own refers to the companion object inside that class. So to get that syntax, you'd need to have a companion object inside every class that you want to use this extension on.
What you can do in a very general way is get the KClass
that describes your class first. This gives you an object (the KClass
instance) that you can then call an extension on:
fun KClass<*>.transformName() {
val clazz: Class<*> = this.java
clazz.name.hashCode()
}
StateA::class.transformName()
Another approach, which is less verbose on the call site could be a generic function like this, where the reified
keyword allows you to access the concrete class that was used as the generic type parameter inside the function:
inline fun <reified T> transformName() {
val clazz: Class<*> = T::class.java
clazz.name.hashCode()
}
transformName<StateA>()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With