用于从子类型推断泛型超类型的 Kotlin 语法
Kotlin syntax for inferring generic supertype from subtype
尝试调用需要 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()
将调用 class 的 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>>)
}
尝试调用需要 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()
将调用 class 的 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>>)
}