Issue
Suppose we have a structure like this:
data class MyClass(
val inner: MyInnerClass
) {
data class MyInnerClass(
val foo: String
)
}
How can I get the relative class name MyClass.MyInnerClass
? I already have a KType of that class. And if I look at this with the debugger I can find the name:
I could not find out how to access this with code.
Solution
This is possible using the kotlin-reflect artifact as a dependency. https://kotlinlang.org/docs/reflection.html#jvm-dependency
In my Maven project I add a new dependency:
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
I didn't use Gradle for this, but I think you'd use
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.0")
}
to include it.
I made a data class similar to yours in a package named innerclass
:
package innerclass
data class MyClass(
val inner: MyInnerClass
) {
data class MyInnerClass(val foo:String)
data class AnotherInnerClass(val bar:String)
}
Then my Main.kt looks like this:
import innerclass.MyClass
import kotlin.reflect.KClass
fun main(args: Array<String>) {
println("Using class type as reference: ${MyClass::class.qualifiedName}")
printRelativeClassNames(MyClass::class.nestedClasses)
val test = MyClass(MyClass.MyInnerClass("foo"))
println("\nUsing instance as reference: ${test::class.qualifiedName}")
printRelativeClassNames(test::class.nestedClasses)
}
private val KClass<*>.packageFqName: String?
get() {
return java.`package`.name
}
private val KClass<*>.relativeClassName: String?
get() {
return qualifiedName?.removePrefix("${packageFqName}.")
}
fun printRelativeClassNames(nestedClasses: Collection<KClass<*>>) {
nestedClasses.forEach {
println("Actual Kotlin class: $it")
println(it.relativeClassName)
}
}
When I run the program, it outputs:
Using class type as reference: innerclass.MyClass
Actual Kotlin class: class innerclass.MyClass$AnotherInnerClass
MyClass.AnotherInnerClass
Actual Kotlin class: class innerclass.MyClass$MyInnerClass
MyClass.MyInnerClass
Using instance as reference: innerclass.MyClass
Actual Kotlin class: class innerclass.MyClass$AnotherInnerClass
MyClass.AnotherInnerClass
Actual Kotlin class: class innerclass.MyClass$MyInnerClass
MyClass.MyInnerClass
Using reflection (and a little string manipulation) I can get the Kotlin class as well as print out the relative name of the class.
Let me know if you hit any issues.
Answered By - Justin Gilman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.