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

Accidental override: The following declarations have the same JVM signature

这部分我在 Kotlin 中遇到错误:

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

private val context: Context

在日志中它说:

Error:(14, 25) Accidental override: The following declarations have the same JVM signature
(getContext()Landroid/content/Context;):  
    fun <get-context>(): Context  
    fun getContext(): Context!

我看不出问题的原因。

发生这种情况是因为 Kotlin 编译器试图为 class 主构造函数中声明的 val context 生成一个 getter,即方法 getContext(),但是基础 class ArrayAdapter<T> already has such a method.

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

  • 将您的 class' 构造函数参数更改为 val.

       class GitHubRepoAdapter(context: Context, ...
    

    在这种情况下,不会产生getter,冲突也就消失了。

    在您的情况下,这似乎是更可取的解决方案,因为即使没有重新声明,.

  • 使用@JvmName annotation, apply it to the context property getter:

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

    这将使编译器生成带有另一个 JVM 名称(在注释中指定的名称)的 getter,从而避免冲突,但是从 Java 访问它不太直观(特别是因为将有两个类似的功能)。在 Kotlin 中,您仍然可以使用 属性 及其原始名称 context.

除了已经给出的答案...

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

在class声明中,构造函数声明中的参数通常不仅仅是参数。使用 valvar,您实际上是在声明 属性 成员(不仅仅是参数)。随着 属性 成员自动出现 "getters"(在 var 的情况下 "setters")。在 OP 的情况下,自动 getter 称为 getContext() 但是 基础 class 已经有一个 getContext() (相同的签名)。

最有可能的是,这里的目的只是将 context 传递给 super,在这种情况下,其他答案效果最好。但是,在需要新 属性 的情况下,但所选名称与 super 的不同目的成员冲突,则更改名称是替代方案。

简而言之,当您确实想要一个新成员变量时,更改名称适用] 超级 class 已经公开了同名的不同成员。

将变量名称更改为 myContext,这样就可以毫无问题地与您一起工作。

有类似的问题,有效的方法是确保我的 targetSdkVersioncompileSdkVersion 在所有模块中都相同。

我想在这里补充一点:

当您将参数命名为 context 时,它将与默认情况下也是 context 的基本 class 参数名称冲突。因此,更改参数名称会对您有所帮助。