让非泛型类在构造函数中使用泛型参数

我想在kotlin中有一个非泛型的类,在其构造函数中使用泛型来指定一个参数。 但是,我不知道如何做到这一点,Intellij的Java-to-Kotlin转换器打破了。

我的java类看起来像这样

public class Test { interface I1 { } interface I2 { } private final I1 mI1; private final I2 mI2; public <T extends I1 & I2> Test(T host) { mI1 = host; mI2 = host; } } 

转换器的输出看起来像这样。

 class Test(host: T) where T: I1, T: I2 { internal interface I1 internal interface I2 private val mI1: I1 private val mI2: I2 init { mI1 = host mI2 = host } } 

我想这样做是因为在Android开发中,能够指定一个类似于<Host extends Context & CustomCallbackInterface>的构造函数参数是很有用的,

看着Kotlin的语法 ,现在看来这是不可能的。 对于主构造函数,类型参数表示类类型参数:

 class (used by memberDeclaration, declaration, toplevelObject) : modifiers ("class" | "interface") SimpleName typeParameters? primaryConstructor? (":" annotations delegationSpecifier{","})? typeConstraints (classBody? | enumClassBody) ; 

对于二级构造函数,没有可能的类型参数:

 secondaryConstructor (used by memberDeclaration) : modifiers "constructor" valueParameters (":" constructorDelegationCall)? block ; 

但是,构造函数只是一个特殊的功能。 如果我们不使用构造函数,而是使用我们自己的函数,我们可以想出以下几点:

 class Test { interface I1 interface I2 private val mI1: I1 private val mI2: I2 internal constructor(host: I1, host2: I2) { mI1 = host mI2 = host2 } companion object { fun <T> create(host: T): Test where T : Test.I1, T : Test.I2 { return Test(host, host) } } } fun <T> test(host: T): Test where T : Test.I1, T : Test.I2 { return Test(host, host) } 

我们现在可以调用Test.create(host)或者test(host)来创建一个实例。

在nhaarman的答案上扩展你可以使用运算符重载使Test的伴侣对象实现invoke operator

 class Test { interface I1 interface I2 private val mI1: I1 private val mI2: I2 private constructor(i1: I1, i2: I2) { mI1 = i1 mI2 = i2 } companion object { operator fun <T> invoke(host: T): Test where T : I1, T : I2 { return Test(host, host) } } } 

然后,您可以使用所需的调用语法创建一个Test对象:

 Test(object : Test.I1, Test.I2 {})