Nik*_*laB 8 generics abstract-class type-inference kotlin
我正在尝试使用泛型参数创建一个抽象类,它将具有应该调用方法而不必指定类型参数的子类.到目前为止我有这个:
abstract class AbstractClass<T : Any> @Autowired constructor(protected val delegate: MyService) {
inline fun <T: Any> myMethod(param: Any): T? {
return delegate.myMethod(param).`as`(T::class.java)
}
}
Run Code Online (Sandbox Code Playgroud)
并实施:
class TesterWork @Autowired constructor(delegate: MyService) : AbstractClass<Tester>(delegate) {
}
Run Code Online (Sandbox Code Playgroud)
现在在调用时myMethod我必须指定类型参数:
testerWork.myMethod<Tester>("test")
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以自动推断出类型参数?我可以以某种方式重写myMethod吗?请注意,我需要T::class.java在方法内部.
您不能将类的泛型参数用作具体化的泛型(获取其T::class令牌),因为在运行时,泛型参数被删除:Kotlin遵循Java的类型擦除实践,并且没有针对类的具体化泛型.
(Kotlin 仅为内联函数修改了泛型)
鉴于此,您可以通过并存储Class<T>令牌以便您可以使用它.
此外,myFunction在您的示例中引入了一个泛型参数,它将是一个新的泛型,不以任何方式连接到类泛型参数(命名两者T只会增加混淆,考虑它们T1和T2).如果我做对了,你的意思就是"通用".
您可以做的是声明一个抽象val,它将存储一个类令牌并重写该函数,以便它使用存储的类令牌:
abstract class AbstractClass<T : Any> constructor(protected val delegate: MyService) {
protected abstract val classToken: Class<T>
fun myMethod(param: Any): T? {
return delegate.myMethod(param).`as`(classToken)
}
}
Run Code Online (Sandbox Code Playgroud)
然后,派生AbstractClass将需要覆盖classToken:
class TesterWork constructor(delegate: MyService) : AbstractClass<Tester>(delegate) {
override val classToken = Tester::class.java
}
Run Code Online (Sandbox Code Playgroud)
之后,您将能够在TesterWork实例上调用该函数,而无需指定泛型参数:
val service: MyService = ...
val t: Tester? = TesterWork(service).myMethod("test")
Run Code Online (Sandbox Code Playgroud)