让非泛型 class 在构造函数中采用泛型参数
Have a Non-Generic class take a generic argument in constructor
我想在 kotlin 中有一个非泛型 class,它在其构造函数中使用泛型来指定一个参数。但是,我不知道该怎么做,Intellij 的 Java-to-Kotlin 转换器中断了。
我的javaclass看起来像这样
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的grammar,目前看来是不行的。对于主构造函数,类型参数表示 class 类型参数:
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's you can use operator overloading to make Test
's companion object 实施 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 {})
我想在 kotlin 中有一个非泛型 class,它在其构造函数中使用泛型来指定一个参数。但是,我不知道该怎么做,Intellij 的 Java-to-Kotlin 转换器中断了。
我的javaclass看起来像这样
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的grammar,目前看来是不行的。对于主构造函数,类型参数表示 class 类型参数:
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's Test
's companion object 实施 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 {})