Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Kotlin中具有两个类型参数的泛型类 类映射生成器{ 运算符fun invoke(arg:T):MapBuilder{ 还这个 } 操作符乐趣调用(arg:U):MapBuilder{ 还这个 } }_Java_Generics_Kotlin_Legacy - Fatal编程技术网

Java Kotlin中具有两个类型参数的泛型类 类映射生成器{ 运算符fun invoke(arg:T):MapBuilder{ 还这个 } 操作符乐趣调用(arg:U):MapBuilder{ 还这个 } }

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

当然,由于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(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