当前位置: 首页 > 知识库问答 >
问题:

Kotlin冲突重载:public open fun statements()

秦晋
2023-03-14

我有一个可持久化的接口,如下所示

public interface Persistable {

    <T extends Statement<T>> List<Statement<T>> statements();

}

此java接口由Kotlin类A继承,因此

data class UpdateRule(
        private val something: S) : Persistable {

    override fun statements(): List<Statement<BoundStatement> {
        return PutKeyValue(Function(orgId, serviceId), JsonUtil.toJson(rule)).statements() //this returns BoundStatement
    }
}

但是,这会产生错误,导致重载冲突。这段代码似乎在Java中工作(虽然有警告),但在Kotlin中它根本不允许,如何解决这一问题,同时确保父接口对绑定语句和简单语句都是通用的?

共有2个答案

阎承
2023-03-14

在Java就像在Kotin中一样,泛型方法的类型参数的值由方法的调用者确定,并且在方法的每次调用中可能不同,即使在同一个实例上也是如此。

在您的特定情况下,对于这样声明的Java接口,statements()应该以这样的方式实现,调用方可以选择对该方法的给定调用将返回哪种类型的语句。在您的实现中并非如此,这就是Kotlin不允许这样做的原因。正如@Sweeper所指出的,Java在这方面存在缺陷,可能会让您得到警告。

当使用泛型类或接口时,这是不同的。如果您在类/接口级别定义类型参数,那么该类型参数的值在类的构建时确定,或者可以由子类修复。对于给定的实例,对该方法的所有调用都将返回一个众所周知的类型,这是(我相信)您在这里想要的。

您可以在Java中执行此操作:

public interface Persistable<T extends Statement<T>> {

    List<Statement<T>> statements();
}

然后在科特林:

data class UpdateRule(
        private val something: S
) : Persistable<BoundStatement> {

    override fun statements(): List<BoundStatement> {
        return PutKeyValue(Function(orgId, serviceId), JsonUtil.toJson(rule)).statements() //this returns BoundStatement
    }
}
夹谷野
2023-03-14

您似乎误解了持久化中泛型的含义。正如现在编写的那样,您应该实现语句方法,以便它可以处理扩展语句的任何类型的

它只在Java中产生警告,因为Java的泛型被破坏了。由于类型擦除,列表

要解决此问题,可以将泛型类型参数移动到接口

public interface Persistable<T extends Statement<T>> {
    List<Statement<T>> statements();
}
data class UpdateRule(private val something: S) :     
    Persistable<BoundStatement> {

    override fun statements(): List<BoundStatement> =
        PutKeyValue(Function(orgId, serviceId), JsonUtil.toJson(rule)).statements()
}

请注意,当我们实现接口时,我们现在可以指定我们正在实现的特定T

 类似资料:
  • 我见过其他的链接错误,但没有一个能说明如何使用罐子。当我在Jboss中部署我的应用程序时,它可以正常工作,但当我将应用程序部署到websphere时,我遇到了这种链接错误。在这里可以找到一个类似的问题:调用webservice方法时出现LinkageError,但不确定如何修复它 它主要是从和加载的,带有共享类 我所拥有的是jsp调用Web服务。从消息中,我看到的唯一jars来自axis.jar,

  • 我在WebSphereApplicationServer(8.5.5.14)中遇到了LinkageError。这里也发现了类似的问题LinkageError 原因:java。lang.LinkageError:解析方法“javax/xml/soap/SOAPElement.getElementQName()Ljavax/xml/namespace/QName;”时加载约束冲突:loader“com

  • 我有一个工作应用程序,但我想改进一点。方法(“private fun save”),负责保存我需要的信息,我希望使其异步。 但问题是,当我把它改成——“私有挂起fun save”的时候,我要做suspend和override fun拦截方法。但是由于它被覆盖,我得到一个错误: 冲突重载:public open suspend fun intercept(链:Interceptor.chain):c

  • 小雪再 pull 的时候遇到了冲突。 → git pull --rebase remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects

  • 以下声明在科特林是合法的。 作为字节码,我们得到: 也可以从Kotlin调用这两个方法。 当我试图从Java调用它们中的任何一个时,问题就出现了: 模棱两可的调用。两种方法都匹配… 如何避免这样的问题?如何处理这些方法?若第三方kt库也有同样的问题怎么办? 上面的例子是一个合成的例子。

  • 我正在将Java中的一些类转换为kotlin,当试图从接口继承时,我遇到了编译错误: 平台声明冲突:以下声明具有相同的JVM签名(getContentID()ljava/lang/string;): 下面是课程: 我对Kotlin来说是超级新的。