代码之家  ›  专栏  ›  技术社区  ›  lannyf

为什么一个得到“平台声明冲突”,而另一个是好的?

  •  0
  • lannyf  · 技术社区  · 7 年前

    interface IData {
    
        fun getHash() : Int
        fun getUUID(): UUID
    
        ......
    }
    

    正在尝试为接口创建对象。这个 fun getUUID(): UUID fun getHash() : Int 错误如下。

    有什么问题吗?为什么它们不同?

    fun buidlDataList () : ArrayList<IData> {
    
        val dataList = ArrayList<IData>(0)
    
        dataList.add(object : IData {
    
            val hash: Int by lazy { dataFetchers.size+System.currentTimeMillis().toInt() } //<=== get error
            override fun getHash(): Int {                                                  //<=== get the same error
                return hash
            }
    
            val uuid: UUID by lazy { UUID.randomUUID() }
            override fun getUUID(): UUID {
                return uuid
            }
            ......
        }
    }
    
    
    Platform declaration clash:  The following declarations have the same JVM signature(getHash() I):
        * public final fun <get-hash>(): int  defined in com.data. buidlDataList <no name provided>
        * public open fun getHash(): int defined in defined in com.data. buidlDataList <no name provided>
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Zoe - Save the data dump 张群峰    7 年前

    变量创建它们自己的getter,但是您也可以显式地定义它们。当您声明var或val时,它们通常会自动生成自己的getter 1

    但在所有其他情况下:

    val x: Int = TODO()
    

    生成一个getter 1

    在您的情况下,我建议直接在接口中使用val。您可以看到,生成的getter与显式声明的getHash方法具有相同的名称。getter也不会重写方法(除非您使用@Jvm注释之一对其进行注释,我不记得是哪个注释,但您实际上并不需要这些注释)。

    interface IData {
        val hash: Int
        val uuid: UUID
    }
    

    移除覆盖对象中的getter,然后添加 override 至VAL:

    dataList.add(object : IData {
        override val hash: Int by lazy { dataFetchers.size+System.currentTimeMillis().toInt() }
        override val uuid: UUID by lazy { UUID.randomUUID() }
    }
    

    第一个接口实际上相当于用get和set方法声明一个接口。如果您从Java重写它,它将要求您重写 getHash() getUid() ,并且需要在本地声明字段。Kotlin的工作方式不同,因为它自动生成setter。


    另外,如果您反编译Kotlin字节码,您将看到带有变量的接口编译成什么:

    public interface IData {
       int getHash();
    
       @NotNull
       UUID getUuid();
    }
    

    所以它与您最初使用的完全相同,只是子类中没有因为变量名冲突而发生冲突。


    val uuid 创建名为 getUuid ,而接口声明 getUUID UUID

    1:假设变量/常量不在方法中。顶级变量、接口中的变量、枚举、类、对象和伴随对象都会生成getter/setter,但是如果在方法中声明变量,那么在适用的地方就不会有getter和setter。