Kotlin抽象类与泛型参数和使用类型参数的方法 [英] Kotlin abstract class with generic param and methods which use type param

查看:2263
本文介绍了Kotlin抽象类与泛型参数和使用类型参数的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个具有泛型参数的抽象类,该泛型参数将具有应该调用方法而不必指定类型参数的子类。
我到目前为止:

 抽象类AbstractClass< T:Any> @Autowired构造函数(protected val delegate:MyService){
inline fun< T:Any> myMethod(param:Any):T? {
return delegate.myMethod(param).`as`(T :: class.java)
}
}
$ b


$ b
$ b <$ p $ class> TesterWork @Autowired构造函数(delegate:MyService) :AbstractClass< Tester>(delegate){
}

  testWork.myMethod< Tester>(测试)

我想知道是否可以自动推断类型参数?
我可以以某种方式重写myMethod吗?请注意,我需要在方法中包含 T :: class.java

>

不能使用类的泛型参数作为泛化参数(获取它的 T :: class 标记),因为在运行时通用参数被删除:Kotlin遵循 Java的类型删除练习,并且没有类的泛化泛型。

(Kotlin的泛化的泛型仅限内联函数)



鉴于此,您需要传递并存储 Class< T>



此外, myFunction 一个泛型参数,它将是一个新泛型,并不以任何方式连接到类泛型参数(命名 T 只会增加混淆,请考虑它们 T1 T2 )。如果我理解正确,那么你的意思是类的泛型。

可能你可以做的是声明一个抽象 val 将存储一个类标记并重写该函数,以便它使用存储的类标记:

 抽象类AbstractClass< T :任何>构造函数(protected val delegate:MyService){
protected abstract val classToken:Class< T>

fun myMethod(param:Any):T? {
return delegate.myMethod(param).`as`(classToken)
}
}

然后,从 AbstractClass 派生将需要重写 classToken

 类TesterWork构造函数(delegate:MyService):AbstractClass< Tester>(delegate){
override val classToken = Tester :: class.java
}

之后,您将可以调用 TesterWork 实例,而不指定泛型参数:

  val service:MyService = ... 
val t:测试者? = TesterWork(service).myMethod(test)


I'm trying to create an abstract class with generic parameter which will have subclasses which should call methods without having to specify type parameters. I have this so far:

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)
    }
}

And implementation:

class TesterWork @Autowired constructor(delegate: MyService) : AbstractClass<Tester>(delegate) {
}

Now when calling myMethod I have to specify the type argument:

testerWork.myMethod<Tester>("test")

I was wondering would it be possible to infer the type argument automatically? Can I somehow rework myMethod? Note that I need to have T::class.java inside the method.

解决方案

You cannot use a class' generic parameter as a reified generic (getting its T::class token), because at runtime the generic parameter is erased: Kotlin follows Java's type erasure practice and doesn't have reified generics for classes.
(Kotlin has reified generics only for inline functions)

Given that, it's up to you to pass and store a Class<T> token so that you can use it.

Also, myFunction in your example introduces a generic parameter, and it will be a new generic, not connected to the class generic parameter in any way (naming both T only adds confusion, consider them T1 and T2). If I get it right, you meant the class' generic instead.

Probably what you can do is declare an abstract val that would store a class token and rewrite the function so that it uses the stored class token:

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)
    }
}

Then, deriving from AbstractClass will require overriding the classToken:

class TesterWork constructor(delegate: MyService) : AbstractClass<Tester>(delegate) {
    override val classToken = Tester::class.java
}

After that, you will be able to call the function on TesterWork instance without specifying the generic parameter:

val service: MyService = ...
val t: Tester? = TesterWork(service).myMethod("test")

这篇关于Kotlin抽象类与泛型参数和使用类型参数的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆