从子类型推断泛型超类型的Kotlin语法
试图调用需要从子类型推断泛型超类型的Kotlin语法,kotlin,kotlin-interop,Kotlin,Kotlin Interop,试图调用需要类作为参数的现有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
类作为参数的现有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
}
package.com.example
//在别人的库中准确导入Java代码
抽象类Java代码{
有趣的事情(事情:课堂){
//行得通
}
}
//我的代码
类KotlinCode:JavaCode(){
有趣的开始{
doTheThing(KotlinCode::class.java)
}//^类型推断失败。应为类型不匹配
}
但编译时不会出现以下错误:
Type inference failed. Expected type mismatch: inferred type is Class<KotlinCode> but Class<JavaCode<String>> was expected
类型推断失败。预期类型不匹配:推断类型为类,但预期为类
因此,我尝试强制演员阵容(如中所示):
hello(genericalargument::class.java作为类)
但这有一个警告:
Unchecked cast: Class<KotlinCode> to Class<JavaCode<String>>
未选中强制转换:类到类
那么正确的语法是什么呢?是否相关?您的代码中有几个问题
首先,Callable
不等于Callable
Callable
表示参数可以是String
或null
,但Callable
只能是String
其次,Class
不实现Class
,但genericalargument
实现Callable
。他们是不同的。您可以将其改为使用泛型
private fun <T : Callable<String>> hello(callable: Class<T>) {
System.out.println(callable.toString())
}
此外,Kotlin允许将函数作为参数传递或使用SAM作为接口。不需要为可调用的实现
编辑:当op更新问题时
@Suppress("UNCHECKED_CAST")
fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) {
doTheThing(thing as Class<JavaCode<T>>)
}
@Suppress(“未选中的\u CAST”)
有趣的JavaCode.doTheThing2(东西:类){
做事情(像课堂一样)
}
您的代码中有几个问题
首先,Callable
不等于Callable
Callable
表示参数可以是String
或null
,但Callable
只能是String
其次,Class
不实现Class
,但genericalargument
实现Callable
。他们是不同的。您可以将其改为使用泛型
private fun <T : Callable<String>> hello(callable: Class<T>) {
System.out.println(callable.toString())
}
此外,Kotlin允许将函数作为参数传递或使用SAM作为接口。不需要为可调用的实现
编辑:当op更新问题时
@Suppress("UNCHECKED_CAST")
fun <T, U : JavaCode<T>> JavaCode<T>.doTheThing2(thing: Class<U>) {
doTheThing(thing as Class<JavaCode<T>>)
}
@Suppress(“未选中的\u CAST”)
有趣的JavaCode.doTheThing2(东西:类){
做事情(像课堂一样)
}
因为可调用
!=Callable
,您是否尝试声明class GenericArgument:Callable
?这只是将预期的类型不匹配更改为class
。因为Callable
!=Callable
,您是否尝试声明class genericalargument:Callable
?这只会将预期的类型不匹配更改为class
。我知道String
和String?
之间存在差异。在那之后,也许我的例子有点不对劲。它实际上是我正在扩展的一个抽象Java类。我想在基类上使用的方法。这是其他人的图书馆,使更改变得困难。它实际上不是一个可调用的;这只是提供了一个同样问题的例子。我还意识到,callable.toString()
并不是特别有用。这再次证明了这一点。听起来好像我必须更改被调用方(hello
),但调用方(call
)是我可以修改的位。@AlexTaylor Java在运行时没有泛型元数据,因此泛型强制转换可能会导致错误。Kotlin没有提供防止这种错误的功能吗?基本上,Java代码在这种情况下无法提供运行时类型安全性,但是Kotlin给了您一个警告?我已经用更接近真实代码的内容更新了代码。@这是JVM限制,而不是Java代码。Kotlin编译代码以在JVM上运行。Kotlin会给你一个警告,因为它无法被检查。在我出去吃午饭的时候,我将不得不查看您的代码。好的,我们将强制转换分离为一个函数,这样抑制只会影响问题代码。明白了。我知道String
和String?
之间有区别。在那之后,也许我的例子有点不对劲。它实际上是我正在扩展的一个抽象Java类。我想在基类上使用的方法。这是其他人的图书馆,使更改变得困难。它实际上不是一个可调用的;这只是提供了一个同样问题的例子。我还意识到,callable.toString()
并不是特别有用。这再次证明了这一点。听起来好像我必须更改被调用方(hello
),但调用方(call
)是我可以修改的位。@AlexTaylor Java在运行时没有泛型元数据,因此泛型强制转换可能会导致错误。Kotlin没有提供防止这种错误的功能吗?基本上,Java代码在这种情况下无法提供运行时类型安全性,但是Kotlin给了您一个警告?我已经用更接近真实代码的内容更新了代码。@这是JVM限制,而不是Java代码。Kotlin编译代码以在JVM上运行。Kotlin会给你一个警告,因为它无法被检查。在我出去吃午饭的时候,我将不得不查看您的代码。好的,我们将强制转换分离为一个函数,这样抑制只会影响问题代码。知道了。