I have a question about generic in kotlin

末鹿安然 提交于 2021-02-05 10:45:14

问题


I got an error. Like this :

Error 1 : Platform declaration clash: The following declarations have the same JVM signature (getData()Ljava/lang/Object;): fun (): I defined in typeErasure2 fun getData(): I defined in typeErasure2

Error 2 : Platform declaration clash: The following declarations have the same JVM signature (getData()Ljava/lang/Object;): fun (): I defined in typeErasure2 fun getData(): I defined in typeErasure2

fun main(args : Array<String>){
    var te = typeErasure("Jennie")
    println(te.getData())
    var te2 = typeErasure2("Sam")
    println(te2.getData())
}

class typeErasure<I>(name : I){
    private val data : I = name
    fun getData() : I = data
}

class typeErasure2<I>(name : I){
    val data : I = name          // error 1
    fun getData() : I = data     // error 2
}

when I use the private keyword the program can run, otherwise it will get an error. anyone can explain to me? :)


回答1:


Kotlin's logic of properties differ slightly from Java's fields.

Whenever you declare any variable in class, its getter and setters are automatically generated, and they can be customized with get() or set {} after it.

Declaring getVariable() manually will result in platform clash, as getter is already defined for the field in the variable declaration and you are creating function with the same name as well.

You can use @JvmField annotation to instruct the compiler to not generate any getter or setter for the field.

@JvmField
val data: I = name

fun getData(): I = data



回答2:


This has nothing to do with generics. The problem with your code is that

public fun getData(): I

Is an accesor for "data". But when "data" is a public field, then the accesor is redundant. So when you do:

val someValue = myObject.data

Then the compiler cannot tell if it should use the accessor getData() or it should just point to the field directly.

When getData is private, then the compiler clearly knows that it can't use it so then it will point to the field directly.

class typeErasure2<I>(name : I){
    val data : I = name
    fun getData() : I = data
}

fun main() {
    val obj = typeErasure2<Int>(123)
    println(obj.data) // <--- Ask yourself, what does this line do exactly?
}
class typeErasure2<I>(name : I){
    val data : I = name
    private fun getData() : I = data
}

fun main() {
    val obj = typeErasure2<Int>(123)
    println(obj.data) // <--- Here it is clear
    // it is not the "getData" because that one is private,
    // so it must be the public field "data" you are pointing to
}


来源:https://stackoverflow.com/questions/64748367/i-have-a-question-about-generic-in-kotlin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!