Kotlin 如何克服;“相同的JVM签名”;实现Java接口时出错?

Kotlin 如何克服;“相同的JVM签名”;实现Java接口时出错?,kotlin,Kotlin,使用下面的代码,我在IntelliJ IDEA 13.1.6和Kotlin插件0.11.91.AndroidStudio.3中遇到以下错误: Platform declaration clash: The following declarations have the same JVM signature (getName()Ljava/lang/String;): • public open fun getName(): kotlin.String? • internal final

使用下面的代码,我在IntelliJ IDEA 13.1.6和Kotlin插件0.11.91.AndroidStudio.3中遇到以下错误:

Platform declaration clash: The following declarations have the same JVM signature (getName()Ljava/lang/String;):
  • public open fun getName(): kotlin.String?
  • internal final fun <get-name>(): kotlin.String?
Kotlin类,
KotlinClass.kt

public class KotlinClass(val name: String?) : JavaInterface
我已尝试通过以下方式重写“getter”方法 添加
override fun getName():字符串?=name
,但这会产生相同的错误

我可以看到这样做的一种解决方法:

public class KotlinClass(val namePrivate: String?) : JavaInterface {
  override fun getName(): String? = namePrivate
}

但在我的现实世界中,我有许多属性需要实现,也需要setter。对每一处房产这样做似乎不是很科特林式的。我遗漏了什么?

另一个解决方法是在抽象Kotlin类中声明属性,然后编写一个扩展KotlinClass并实现JavaInterface的小型java类

// JavaInterface.java
public interface JavaInterface {
    int getFoo();
    void setFoo(int value);
}

// KotlinClass.kt
abstract class KotlinClass(open var foo : Int = 0) {
}

// JavaAdapter.java
class JavaAdapter extends KotlinClass implements JavaInterface {
    // all code in KotlinClass, but can't implement JavaInterface there
    // because kotlin properties cannot override java methods.
}

将该变量设置为私有可以解决问题


公共类KotlinClass(private val name:String?):JavaInterface

我们发现,要使用相同的名称而不发生冲突,ctor args必须是private,并且您必须仍然覆盖接口方法。您不需要任何额外的支持字段。此外,表达式体赋值不会递归,因此可以安全地使用该语法

public interface JavaInterface {
    public String getName();
}

public class KotlinClass(val namePrivate: String?) : JavaInterface {

private var name = namePrivate

    override fun getName(): String? {
        return name
    }
}
Java接口

interface IUser {
    String getUserScope();
    String getUserId();
}
科特林班

class SampleUser(private val userScope: String, private val userId: String) : IUser {
    override fun getUserId() = userId
    override fun getUserScope() = userScope
}

可以使用@JvmField来指示编译器不生成getter/setter,并且可以实现setter和getter。这样,您的代码在Java(作为属性getter/setter)和Kotlin(作为属性)中运行良好

例如: JAVA

public interface Identifiable<ID extends Serializable> 
{
   ID getId();
} 
class IdentifiableImpl(@JvmField var id: String) :Identifiable<String> 
{
   override fun getId(): String 
   {
       TODO("not implemented")
   }
}
可识别的公共接口
{
ID getId();
} 
KOTLIN

public interface Identifiable<ID extends Serializable> 
{
   ID getId();
} 
class IdentifiableImpl(@JvmField var id: String) :Identifiable<String> 
{
   override fun getId(): String 
   {
       TODO("not implemented")
   }
}
class-identiableimpl(@JvmField-var-id:String):可识别
{
重写fun getId():字符串
{
待办事项(“未实施”)
}
}

如果您可以直接控制接口,那么最好的方法是用Kotlin编写接口。然后你可以编写你的类

public class KotlinClass(override val name: String?) : KotlinInterface

并且仍然使用与以前相同的接口从任何Java代码引用它。这看起来比将所有属性设置为private并重写get函数要整洁得多。显然,如果您无法将接口迁移到Java,因为您不拥有它,那么这似乎是唯一的解决方案。

我认为最可读的组合是通过单表达式函数实现字段+显式接口(结合@Renato Garcia和@Steven Spungin的答案):

爪哇:

科特林:

class Implementation(@JvmField val foo: String) : SomeInterface {
    override fun getFoo() = foo
}

将变量重命名为其他名称,或者如果不希望它是公共的,则将其设为私有。

名为
@JvmName
的Kotlin注释功能将解决Java和Kotlin中签名相同时的重复问题

fun function(p: String) {
   // ...
}

// Signature: function(Ljava/lang/String)
使用
JvmName
将:

@JvmName("functionOfKotlin")
fun function(p: String) {
   // ...
}

// Signature: functionOfKotlin(Ljava/lang/String)

目前不能使用Kotlin属性重写Java方法。如果我们能够支持它,那就太好了,但是我们不知道如何为混合层次结构始终如一地做到这一点。添加更具描述性的错误消息怎么样?如果说你不能用属性重写java方法……那就不那么合用了。我想最好是在Kotlin中重写接口……关于用Kotlin属性重写getter/setter方法的任何更新?所有这些答案都像是避免名称冲突问题的变通方法,大多数情况下,您只想返回属性@lrn2code这也不起作用。如果您有一个Kotlin类
类KotlinClass(变量名:String):SomeInterface
和一个Kotlin接口
接口SomeInterface{fun getName():String}
,这将在编译期间产生与使用原始Java接口相同的错误。啊,我现在明白了。更好的解决方案是在Kotlin中重写接口时直接在接口中使用属性:当您需要使用Java时仍然没有帮助。我不知道在Kotlin 0.11中是否可能做到这一点,但它在1.1中工作,感觉比使用不同的变量名要好。如果变量需要是公共的?在Kotlin 1.2中对我不起作用:>类“KotlinClass”不是抽象的,并且不实现抽象成员public abstract fun getName():String!在JavaInterface中定义,我觉得这是最好的答案。它直接解决了这个问题,并且适用于其他被接受的答案不能解决的情况,正如@RobertLiberatore所说的,这应该是被接受的答案。