Is there a way to get a Kotlin KType
from a java.lang.reflect.Type
?
Background: I’m working on some code that gets properties/fields from a class and passes them to methods (think JUnit 4 Theories for anyone familiar with those). Because I need Java compatibility, I can’t always use pure Kotlin reflection because calls like MyClass::class.memberProperties
don’t work with raw Java fields.
Another option would be to cast my KType
s to java.lang.reflect.Type
s (via .javaType
), butKType
provides a convenient isSupertypeOf(...)
function that allows comparison between two KTypes
and I haven’t found similar functionality for Java’s Type
.
Very Rough Example:
Kotlin Code:
class KotlinTestClass {
fun test(someParam: List<String>) {
someParam.forEach { println(it) }
}
class CompatibleTypes {
val exact: List<String> = listOf("foo")
val mutable: MutableList<String> = mutableListOf("bar")
val implementation: ImmutableList<String> = immutableListOf("baz")
}
class NonCompatibleTypes {
val wrongParam: List<Int> = listOf(42)
val wrongType: Map<String, String> = mapOf("hello" to "world")
}
}
Java code:
public class JavaTestClass {
public static class CompatibleTypes {
public static final List<String> exact = List.of("foo");
public static final ImmutableList<String> implementation = ImmutableList.of("baz");
}
public static class NonCompatibleTypes {
public static final List<Integer> wrongParam = List.of(42);
public static final Map<String,String> wrongType = Map.of("hello", "world");
}
}
Kotlin Test Code:
fun main(args: Array<String>) {
val parameterType = KotlinTestClass::class.functions.first { it.name == "test" }.parameters[1].type
println("Target: $parameterType")
println("--------------------------------------")
//These should all print "true"
println("Compatible Kotlin types:")
KotlinTestClass.CompatibleTypes::class.memberProperties.asSequence()
.map { it.returnType }
.forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") }
println("--------------------------------------")
println("Compatible Java types:")
//These should all print "true"
//This code doesn't work because the fields aren't valid Kotlin properties
JavaTestClass.CompatibleTypes::class.memberProperties.forEach { println(it) }
JavaTestClass.CompatibleTypes::class.java.declaredFields.asSequence()
.map { it.kotlinProperty?.returnType }
.filterNotNull()
.forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") }
println("--------------------------------------")
println("Non-Compatible Kotlin types:")
//These should all print "false"
KotlinTestClass.NonCompatibleTypes::class.memberProperties.asSequence()
.map { it.returnType }
.forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") }
println("--------------------------------------")
println("Non-Compatible Java types:")
//These should all print "false"
//This code doesn't work because the fields aren't valid Kotlin properties
JavaTestClass.NonCompatibleTypes::class.java.declaredFields.asSequence()
.map { it.kotlinProperty?.returnType }
.filterNotNull()
.forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") }
}