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

时间:2017-05-17 21:45:16

标签: kotlin kotlin-android-extensions kotlin-extension

我在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():上下文       有趣的getContext():上下文!

我无法看到导致问题的原因。

4 个答案:

答案 0 :(得分:52)

这是因为Kotlin编译器尝试为类主构造函数中声明的val context生成一个getter,即方法getContext(),但是基类ArrayAdapter<T> 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("getContext_") private val context: Context, ...
    

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

答案 1 :(得分:18)

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

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

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

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

简而言之,当您执行想要一个新成员变量超级类已经公开了另一个成员时,更改名称就适用同名。

答案 2 :(得分:1)

将变量名更改为myContext,将与您一起正常工作。

答案 3 :(得分:0)

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