Java 意外重写:以下声明在特定类层次结构上具有相同的JVM签名错误

Java 意外重写:以下声明在特定类层次结构上具有相同的JVM签名错误,java,kotlin,Java,Kotlin,在这里,我发现了许多类似的问题,但没有一个解决方案对我没有帮助,因为我的问题的细节。 我有以下类层次结构: com.package.ParentInterface.java public interface ParentInterface { void setMessages(Collection<String> var1); } public class ParentClass { protected Collection messages; publi

在这里,我发现了许多类似的问题,但没有一个解决方案对我没有帮助,因为我的问题的细节。 我有以下类层次结构:

com.package.ParentInterface.java

public interface ParentInterface {
    void setMessages(Collection<String> var1);
}
public class ParentClass {
    protected Collection messages;

    public void setMessages(Collection messages)
    {
        this.messages = messages;
    }
}
public class ChildClass extends ParentClass implements ParentInterface {
}
com.package.ChildClass.java

public interface ParentInterface {
    void setMessages(Collection<String> var1);
}
public class ParentClass {
    protected Collection messages;

    public void setMessages(Collection messages)
    {
        this.messages = messages;
    }
}
public class ChildClass extends ParentClass implements ParentInterface {
}
com.package.KotlinClass.kt

class KotlinClass: ChildClass()
在最后一个Kotlin类中,我有以下错误:`class'KotlinClass'不是抽象的,并且没有实现基类成员公共抽象fun setMessages(var1:(可变)集合!):在com.package.ChildClass中定义的单元

当我接受使用IDE生成方法实现的建议时,我有:

override fun setMessages(var1:MutableCollection?){
}

我在生成的方法上得到以下错误:

意外重写:以下声明具有相同的JVM签名(setMessages(Ljava/util/Collection;)V):

  • public open fun setMessages(messages:(MutableCollection..Collection?):com.package.KotlinClass中定义的单位
  • public open fun setMessages(var1:MutableCollection?):com.package.KotlinClass中定义的单位

我只能更改KotlinClass,因为其他类是Java中第三方库的类。请帮助别人,我已经在这个问题上花了很多时间。

好吧,答案实际上并不像看上去那么严格——是和否。 您可以使用纯kotlin来克服这一限制,但是您会在流程中失去一些功能/可能会在流程中引入一些不必要但明显的错误,因此您应该在继续之前真正调查此方法的使用位置,因为您需要基本上完全“切断”此方法以修复编译错误

因此,在您的具体案例中,我知道您为Kotlin上的Jira开发了Atlassian插件。这很重要,因为我们知道这种方法在你的情况下是可以避免的

问题类别是:
com.atlassian.jira.web.action.JiraWebActionSupport

它实现了以下接口:
com.atlassian.jira.util.ErrorCollection

罪魁祸首的方法是:
void setErrorMessages(收集变量1)

父类是
webwork.action.ActionSupport

它包含
受保护的收集错误消息

这就是你如何切断这条死胡同的方法:

open class SpecificAction : JiraWebActionSupport() {
    override fun setErrorMessages(p0: MutableCollection<String>?) = TODO()
    ...
}
open类特定操作:JiraWebActionSupport(){
重写fun setErrorMessages(p0:MutableCollection?=TODO()
...
}

在您的情况下,Java重写当然更可取,因为您不会丢失任何东西,也不会引入潜在的错误,但是如果您只需要kotlin,并且确保您不会/不会使用此方法,那么这个小的肮脏的黑客将有所帮助。

我有一个与此类似的问题,但这是在如何计算类的内在性方面。它涉及一个函数
getInfo
,该函数同时定义了可空参数和不可空参数

class ChangeFormNPC(input: ByteBuffer, flags: Flags.Int, context: ESSContext) : ess.GeneralElement(), ChangeFormData {
override fun getInfo(analysis: resaver.Analysis?, save: ess.ESS?): String { return ""}
}
我的意思是,在上面的类定义中,
ess.generaleElement()
是问题发生的地方

在那个班

open class GeneralElement protected constructor() : Element {
open fun getInfo(analysis: Analysis, save: ESS): String { return "" }
}
观察到错误消息

<somepath>\ChangeFormNPC.kt: (42, 5): Accidental override: The following declarations have the same JVM signature (getInfo(Lresaver/Analysis;Less/ESS;)Ljava/lang/String;):
    fun getInfo(analysis: Analysis, save: ESS): String defined in ess.ChangeFormNPC
    fun getInfo(analysis: Analysis?, save: ESS?): String defined in ess.ChangeFormNPC
\ChangeFormNPC.kt:(42,5):意外重写:以下声明具有相同的JVM签名(getInfo(Lresaver/Analysis;Less/ESS;)Ljava/lang/String;):
fun getInfo(分析:分析,保存:ESS):在ESS.ChangeFormNPC中定义的字符串
fun getInfo(analysis:analysis?,save:ESS?):在ESS.ChangeFormNPC中定义的字符串
令人困惑的部分(至少对当时的我来说)是,它显示了具有不同可空属性的相同函数


修复方法是将可空说明符添加到
generaleElement
类中的
getinfo
的参数中。这使得getinfo函数相等并删除了错误。

您的
父类使用原始
集合(即没有类型参数的集合)。这是一种专门用于向后兼容预泛型代码的语言特性,您应该绝对避免使用它。如果Kotlin对这样的代码反应非常糟糕,我不会感到惊讶,因为它基本上破坏了类型系统。如果你有一个使用原始的泛型的第三方库,你应该认真地考虑升级或替换它。这是您正在使用的真实代码还是仅用于演示的代码?因为
ChildClass扩展了ParentClass实现了ParentInterface
似乎是个错误<代码>父类实现父接口
对我来说似乎更有效。从
ChildClass
中删除
implements ParentInterface
可以解决问题。@linosays,这是演示代码。但是,它完全描述了第三方库的真正层次结构。我只是通过提出主要问题来简化它。为了回答这个问题:我认为不可能实现/扩展两种在类型擦除后具有相同签名的方法。无论如何,JVM上没有(因为JVM看到签名时,签名是相同的)。Kotlin可能会允许它在其他平台上运行,但前提是牺牲一些互操作性,所以我不认为他们会这么做。