意外覆盖:以下声明具有相同的JVM签名

我在这部分收到了Kotlin的这个错误:

class GitHubRepoAdapter(private val context: Context, private val values: List<GithubRepo>) : ArrayAdapter<GithubRepo>(context, R.layout.list_item, values) { 

私有val上下文:上下文

在日志中说:

错误:(14,25)意外覆盖:以下声明具有相同的JVM签名(getContext()Landroid / content / Context;):fun():上下文fun getContext():Context!

我无法看到造成问题的原因。

发生这种情况是因为Kotlin编译器试图为您的类主构造函数getContext()即函数getContext() val context声明的val context生成一个getter,但是基类ArrayAdapter<T>已经具有这样的函数 。

您可以通过执行以下任一操作来解决该问题:

  • 改变你的类的构造参数不是一个val

      class GitHubRepoAdapter(context: Context, ... 

    在这种情况下,getter将不会被生成,冲突将会消失。

    这似乎是你的情况下的最佳解决方案,因为即使没有重新声明, 也已经有一个从Java getter推断的综合属性context

  • 使用@JvmName注释, 将其应用于context属性getter :

      class GitHubRepoAdapter(@get:JvmName("getContext_") private val context: Context, ... 

    这将使编译器使用另一个JVM名称(在注释中指定的名称)来生成getter,从而避免冲突,但是使用Java访问它不那么直观(特别是因为会有两个相似的函数)。 在Kotlin中,您仍然可以使用该属性的原始名称context

除了已经给出的答案…

  • 或者,您可以保留val (或var ),但将参数的名称更改为不会与超类声明相冲突的名称。

在类声明中,构造函数声明中的参数通常不仅仅是参数。 使用valvar ,你实际上是声明属性成员(不只是参数)。 和财产成员一起来自动“getters”(和var的情况下“setter”)。 在OP的情况下,自动getter被称为getContext() 基类已经有一个getContext()(相同的签名)。

最有可能的是,这里的意图只是将context传递给超级,在这种情况下,另一个答案效果最好。 但是,在需要新财产的情况下,如果选择的名称与超级用户的不同目的相冲突,则更改名称是另一种选择。

简而言之 ,当你想要一个新的成员变量, 但是一个超类已经公开了一个不同的成员时,就改变这个名字。