如何将java.lang.reflect.Type转换为Kotlin的KType?
能否将java.lang.reflect.Type转换为Kotlin的KType?
背景:我正在编写一段从类中获取属性/字段并传递给方法的代码(熟悉JUnit 4 Theories的人可类比理解)。由于需要Java兼容性,我无法始终使用纯Kotlin反射,因为MyClass::class.memberProperties这类调用无法处理原生Java字段。
另一种选择是通过.javaType将KType转换为java.lang.reflect.Type,但KType提供了便捷的isSupertypeOf(...)函数用于比较两个KType,而我在Java的Type中未找到类似功能。
大致示例:
Kotlin代码
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代码
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测试代码
fun main(args: Array<String>) { val parameterType = KotlinTestClass::class.functions.first { it.name == "test" }.parameters[1].type println("Target: $parameterType") println("--------------------------------------") //这些都应输出"true" println("兼容的Kotlin类型:") KotlinTestClass.CompatibleTypes::class.memberProperties.asSequence() .map { it.returnType } .forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") } println("--------------------------------------") println("兼容的Java类型:") //这些都应输出"true" //此代码无法运行,因为这些字段不是有效的Kotlin属性 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("不兼容的Kotlin类型:") //这些都应输出"false" KotlinTestClass.NonCompatibleTypes::class.memberProperties.asSequence() .map { it.returnType } .forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") } println("--------------------------------------") println("不兼容的Java类型:") //这些都应输出"false" //此代码无法运行,因为这些字段不是有效的Kotlin属性 JavaTestClass.NonCompatibleTypes::class.java.declaredFields.asSequence() .map { it.kotlinProperty?.returnType } .filterNotNull() .forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") } }
可以实现将java.lang.reflect.Type转换为Kotlin的KType,以下是两种可行方案:
方案1:使用kotlin.reflect.jvm.TypeToken
通过TypeToken包装Java的Type,直接获取对应的KType,能正确处理泛型等复杂类型:
import kotlin.reflect.jvm.TypeToken fun javaTypeToKType(javaType: java.lang.reflect.Type): KType { return object : TypeToken<Any>(javaType) {}.type }
方案2:调用KotlinReflectionFactory(底层实现)
如果需要更底层的转换方式,可以直接使用Kotlin反射工厂类,注意这属于内部API,版本更新可能会变动:
import kotlin.reflect.jvm.internal.KotlinReflectionFactory fun javaTypeToKType(javaType: java.lang.reflect.Type): KType { return KotlinReflectionFactory.getInstance().createKType(javaType, emptyList()) }
适配你的场景
将测试代码中处理Java字段的逻辑替换为上述转换方法,即可调用isSupertypeOf完成类型兼容性判断:
// 兼容Java类型的处理逻辑 JavaTestClass.CompatibleTypes::class.java.declaredFields.asSequence() .map { javaTypeToKType(it.genericType) } .forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") } // 不兼容Java类型的处理逻辑同理 JavaTestClass.NonCompatibleTypes::class.java.declaredFields.asSequence() .map { javaTypeToKType(it.genericType) } .forEach { println(" - ${parameterType.isSupertypeOf(it)} ($it)") }
内容的提问来源于stack exchange,提问作者Cobra1117
相关产品推荐
相关产品推荐

