用于从子类型推断通用超类型的Kotlin语法
试图将期望Class
作为参数的现有Java代码调用,我在Kotlin中尝试了这个代码:
package com.example //Acutally imported Java code in someone elses's library abstract class JavaCode<T> { fun doTheThing(thing: Class<JavaCode<T>>) { //Does work } } //My code class KotlinCode : JavaCode<String>() { fun startTheThing() { doTheThing(KotlinCode::class.java) } // ^ Type inference failed. Expected type mismatch }
但是,这不会编译以下错误:
Type inference failed. Expected type mismatch: inferred type is Class<KotlinCode> but Class<JavaCode<String>> was expected
所以我试图强制施放(正如在这个答案中所建议的):
hello(GenericArgument::class.java as Class<Callable<String>>)
但是有一个警告:
Unchecked cast: Class<KotlinCode> to Class<JavaCode<String>>
那么什么是正确的语法使用? 这是相关的吗?
你的代码有几个问题。
首先, Callable<String?>
不等于Callable<String>
。 Callable<String?>
表示参数可以是String
或null
但Callable<String>
仅为String
。
其次, Class<GenericArgument>
不实现Class<Callable<String>>
但GenericArgument
实现了Callable<String>
。 他们是不同的。 你可以改变它来使用通用的。
private fun <T : Callable<String>> hello(callable: Class<T>) { System.out.println(callable.toString()) }
现在,通用参数由Callable<String>
绑定。
第三, callable.toString()
可能不会做你想要的。 callable.toString()
将调用类的toString()
而不是对象,例如class com.example.yourclass
。 如果你想调用对象toString()
。 这是正确的。
override fun call(): String { hello(GenericArgument()) return "value" } private fun <T : Callable<String>> hello(callable: T) { System.out.println(callable.toString()) }
而且,Kotlin允许通过函数作为参数或使用SAM作为接口。 Callable
实现是没有必要的。
编辑:如op更新的问题。
@Suppress("UNCHECKED_CAST") fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) { doTheThing(thing as Class<JavaCode<T>>) }