Java Kotlin中具有两个类型参数的泛型类 类映射生成器{ 运算符fun invoke(arg:T):MapBuilder{ 还这个 } 操作符乐趣调用(arg:U):MapBuilder{ 还这个 } }
当然,由于JVM的限制,它无法工作Java Kotlin中具有两个类型参数的泛型类 类映射生成器{ 运算符fun invoke(arg:T):MapBuilder{ 还这个 } 操作符乐趣调用(arg:U):MapBuilder{ 还这个 } },java,generics,kotlin,legacy,Java,Generics,Kotlin,Legacy,当然,由于JVM的限制,它无法工作 class MapBuilder<T,U> { operator fun invoke(arg: T): MapBuilder<T, U> { return this } operator fun invoke(arg: U): MapBuilder<T, U> { return this } } 平台声明冲突:以下声明具有相同的JVM签名(invoke(Lj
class MapBuilder<T,U> {
operator fun invoke(arg: T): MapBuilder<T, U> {
return this
}
operator fun invoke(arg: U): MapBuilder<T, U> {
return this
}
}
平台声明冲突:以下声明具有相同的JVM签名(invoke(Ljava/lang/Object;)Lcom/test/tests/MapBuilder;):
operator fun invoke(arg:T):在com.test.tests.MapBuilder中定义的MapBuilder
operator fun invoke(arg:U):在com.test.tests.MapBuilder中定义的MapBuilder
你知道我如何实现这个吗?这是因为过载冲突 实际上,使用当前参数,
T
可以等于U
。如果您熟悉重载,您应该知道这是不允许的:
Platform declaration clash: The following declarations have the same JVM signature (invoke(Ljava/lang/Object;)Lcom/test/tests/MapBuilder;):
operator fun invoke(arg: T): MapBuilder<T, U> defined in com.test.tests.MapBuilder
operator fun invoke(arg: U): MapBuilder<T, U> defined in com.test.tests.MapBuilder
但举例来说,这是:
fun something(x: Int){ /* foo */ }
fun something(x: Int){ /* bar */ }
因为它们可能是相同的,这将导致冲突。它如何知道调用哪个方法
对于完整范围,编译器会抱怨。如果对一个参数使用:SomeClass
,它将停止抱怨。但这里有一个随机的例子:
fun something(x: Int){ /* foo */ }
fun something(x: Float){ /* bar */ }
类映射生成器{
运算符fun invoke(arg:T):MapBuilder{
还这个
}
操作符乐趣调用(arg:U):MapBuilder{
还这个
}
}
Funt(){
MapBuilder().invoke(LoggerFactory.getLogger(“”)
}
调用
将不明确。只有当你有两种相同的类型时,问题才会出现;它用哪一种
现在,你的MCVE非常小。我不知道你用t和U做什么。因此,我无法给出任何代码示例。但以下是您需要知道的:
任何类型都不能有这两个方法,因为它们可能会冲突。如果使用两个相同的类型,即使使用方差也会导致重载问题。因此,它将排除实例的
MapBuilder
可以使用单个方法,也可以将它们拆分为两个不同名称的方法。该名称显示它是一个生成器,因此您可以使用withKey(T)
和withValue(U)
如果不传递
Class
和Class
并检查它们,就无法直接禁止T==U。不幸的是,即使使用require
或其他契约函数,编译器也不理解这一点。另外,在您尝试之前,使用:Any
是行不通的。这是默认的界限。记住,在Java中,一切都是对象
,在Kotlin中,一切都是Any
您可以使用@JvmName(在的回答中提到)解决这个问题,但是如果您与Java进行互操作,您将使用两个不同的方法名。如果只使用Kotlin,可能会稍微容易一些。Java Kotlin interop有一组
@Jvm*
注释,其中大部分/所有注释都包含在内
即使使用@JvmName,它仍然允许
,直到调用冲突的方法为止。如果要断言T!=不管怎样,你都需要运行类检查 这是因为过载冲突
实际上,使用当前参数,T
可以等于U
。如果您熟悉重载,您应该知道这是不允许的:
Platform declaration clash: The following declarations have the same JVM signature (invoke(Ljava/lang/Object;)Lcom/test/tests/MapBuilder;):
operator fun invoke(arg: T): MapBuilder<T, U> defined in com.test.tests.MapBuilder
operator fun invoke(arg: U): MapBuilder<T, U> defined in com.test.tests.MapBuilder
但举例来说,这是:
fun something(x: Int){ /* foo */ }
fun something(x: Int){ /* bar */ }
因为它们可能是相同的,这将导致冲突。它如何知道调用哪个方法
对于完整范围,编译器会抱怨。如果对一个参数使用:SomeClass
,它将停止抱怨。但这里有一个随机的例子:
fun something(x: Int){ /* foo */ }
fun something(x: Float){ /* bar */ }
类映射生成器{
运算符fun invoke(arg:T):MapBuilder{
还这个
}
操作符乐趣调用(arg:U):MapBuilder{
还这个
}
}
Funt(){
MapBuilder().invoke(LoggerFactory.getLogger(“”)
}
调用
将不明确。只有当你有两种相同的类型时,问题才会出现;它用哪一种
现在,你的MCVE非常小。我不知道你用t和U做什么。因此,我无法给出任何代码示例。但以下是您需要知道的:
任何类型都不能有这两个方法,因为它们可能会冲突。如果使用两个相同的类型,即使使用方差也会导致重载问题。因此,它将排除实例的
MapBuilder
可以使用单个方法,也可以将它们拆分为两个不同名称的方法。该名称显示它是一个生成器,因此您可以使用withKey(T)
和withValue(U)
如果不传递
Class
和Class
并检查它们,就无法直接禁止T==U。不幸的是,即使使用require
或其他契约函数,编译器也不理解这一点。另外,在您尝试之前,使用:Any
是行不通的。这是默认的界限。记住,在Java中,一切都是对象
,在Kotlin中,一切都是Any
您可以使用@JvmName(在的回答中提到)解决这个问题,但是如果您与Java进行互操作,您将使用两个不同的方法名。如果只使用Kotlin,可能会稍微容易一些。Java Kotlin interop有一组
@Jvm*
注释,其中大部分/所有注释都包含在内
即使使用@JvmName,它仍然允许
,直到调用冲突的方法为止。如果要断言T!=不管怎样,你都需要运行类检查 如果给定未知的泛型类型,这些方法可以有效地具有相同的签名。因此,所呈现的基本情况对JVM来说是不明确的。因此,您只需要给它们一个替代名称,JVM(以及Java或其他JVM语言)将从中查看它们。您可以对其中一个或两个文件使用@JvmName
注释来为它们指定内部名称。这不会影响Kotlin和您在Kotlin代码中使用的名称,它们将像以前一样看到它们
class MapBuilder<T, U : Logger> {
operator fun invoke(arg: T): MapBuilder<T, U> {
return this
}
operator fun invoke(arg: U): MapBuilder<T, U> {
return this
}
}
fun t(){
MapBuilder<Logger, Logger>().invoke(LoggerFactory.getLogger(""))
}
错误:(y,x)Kotlin:过载分辨率amb