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

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

问题描述

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

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

和实现:

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

现在在调用 myMethod 时,我必须指定类型参数:

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

testerWork.myMethod<Tester>("test")

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

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.

推荐答案

您不能将类的泛型参数用作具体化泛型(获取其 T::class 标记),因为在运行时泛型参数被删除:Kotlin 遵循 Java 的类型擦除实践,并且没有具体化泛型类.
(Kotlin 有 reified 泛型仅适用于内联函数)

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)

鉴于此,由您来传递和存储 Class 令牌以便您可以使用它.

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

此外,在您的示例中,myFunction 引入了一个泛型参数,它将是一个新的泛型,不以任何方式连接到类的泛型参数(同时命名为 T只会增加混淆,考虑它们 T1T2).如果我没看错,你指的是类的泛型.

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.

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

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

然后,从 AbstractClass 派生将需要覆盖 classToken:

Then, deriving from AbstractClass will require overriding the classToken:

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

之后,您将能够在不指定泛型参数的情况下调用 TesterWork 实例上的函数:

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天全站免登陆