【问题标题】:Accidental override: The following declarations have the same JVM signature意外覆盖:以下声明具有相同的 JVM 签名
【发布时间】:2017-05-17 21:45:16
【问题描述】:

我在这部分的 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 kotlin-android-extensions kotlin-extension


【解决方案1】:

发生这种情况是因为 Kotlin 编译器尝试为类主构造函数中声明的 val context 生成 getter,即方法 getContext(),但基类 ArrayAdapter&lt;T&gt; already has such a method

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

  • 将您的类的构造函数参数更改为不是val

       class GitHubRepoAdapter(context: Context, ...
    

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

    这似乎是您的首选解决方案,因为即使没有重新声明,there is already a synthetic property context inferred from the Java getter

  • 使用@JvmName注解,apply it to the context property getter

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

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

【讨论】:

  • 这是否适用于从接口继承的 val 属性?我的意思是例如与val context: Context的接口?
【解决方案2】:

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

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

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

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

简而言之,当您确实想要一个新的成员变量超类已经通过同名。

【讨论】:

  • 我认为这个版本实际上比公认的答案更可取。如果我的超类已经有一个变量的属性/getter/setter,我为什么要创建第二个呢?删除val/var 似乎肯定是最巧妙的方法。
  • @withoutclass - 您误解了我的回答,我的回答实际上是说您可以保留 val 或 var 并更改变量的名称,这在超类已经使用您选择的第一个名称时很有用。如果超类使用属性名称的目的与您为变量计划的目的完全不同,那么使用不同名称的新属性是合适的。我会更新我的答案以使其更清楚。
【解决方案3】:

将变量名称更改为 myContext 并可以毫无问题地与您一起使用。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我想在这里补充一点:

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

      【讨论】:

        猜你喜欢
        • 2018-07-19
        • 1970-01-01
        • 2020-03-20
        • 2021-08-14
        • 2021-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-31
        相关资源
        最近更新 更多