【问题标题】:How to access Kotlin companion object in Java?如何在 Java 中访问 Kotlin 伴随对象?
【发布时间】:2016-11-02 09:28:47
【问题描述】:

我将我的一个 Java 类转换为 Kotlin 和下面的类。

class MainApplication : Application() {
    companion object {
        operator fun get(context: Context): MainApplication {
            return context.applicationContext as MainApplication
        }
    }
}

它有一个静态函数get

我还有一个 Java 函数可以访问它。

MainApplication application = MainApplication.get(mContext);

当 MainApplication 是 Java 时很好。但是Kotlin中MainApplication的时候不行,上面的代码报错

Error:(27, 54) error: cannot find symbol method get(Context)

如何在上面的 Java 代码中访问 get

【问题讨论】:

    标签: java kotlin


    【解决方案1】:

    可以在伴生对象的方法中添加@JvmStatic注解,让Kotlin生成静态方法。

    class MainApplication : Application() {
        companion object {
            @JvmStatic fun get(context: Context): MainApplication {
                return context.applicationContext as MainApplication
            }
        }
    }
    

    然后您可以像在转换为 Kotlin 之前一样从 Java 访问它:

    MainApplication application = MainApplication.get(mContext);
    

    编辑:我觉得有必要添加一些我最近学到的东西:@JvmStatic 实际上并没有移动方法生成的位置。除了伴生对象上的方法之外,它还通过为 Java 生成静态方法来复制它。我个人认为这不是很好,它可能会根据用例产生一些影响,因此值得了解。

    【讨论】:

    • 不错的一个。好像有两种方法。取决于我们可以改变哪一方(kotlin 或 java)。
    • 勾选这个作为“答案”,因为它更有可能让 Kotlin 与 Java 兼容,而不是相反。 (即人们可能会从 Java 转换到 Kotlin,并使用 Kotlin 代码而不是 Java 代码)。
    • 另一个答案(我的),即使用MainApplication.Companion.get(mContext); 也是一个很好的答案:)
    • 根据官方文档:kotlinlang.org/docs/reference/java-to-kotlin-interop.html 在这种情况下你应该使用@JvmField 而不是@JvmStatic
    • @JvmField 用于属性,而不是函数。见kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-field
    【解决方案2】:

    操作,我明白了。只需使用以下内容。

    MainApplication application = MainApplication.Companion.get(mContext);
    

    【讨论】:

    • 如果您不喜欢默认的Companion名称,也可以命名伴随对象。
    • 当发生重大重构并且您必须更改所有这些地方时,这并不好。另一方面,JvmStatic 选项在很多地方都不需要更改。
    【解决方案3】:

    通过省略伴随对象的名称,必须使用名称 Companion 来访问方法。

    例子:

    class MyClass1 {
        companion object Object1 {
            fun method1 {
            }
        }
    }
    
    class MyClass2 {
        companion object {
            fun method2 {
            }
        }
    }
    

    要调用第一个伴随对象方法,您需要执行以下操作:

    MyClass1.method1()
    

    调用第二个:

    MyClass2.Companion.method2()
    

    有关详细信息,请参阅 Companion Objects 上的 Kotlin 文档。

    【讨论】:

    • 从 Kotlin 1.1.50 开始,您可以通过省略 companion 关键字来调用伴随对象的函数
    • 如果您从 Java 调用伴生对象并且它没有名称,则不会。
    • 我不得不使用MyClass1.Object1.method1(),但这个效果最好,谢谢!
    【解决方案4】:

    如果在方法调用中使用了new 关键字,您可能会遇到无法在Java 中访问Companion 对象的方法的问题。 new 关键字应省略。 documentation 声明:

    Companion 对象及其成员只能通过包含类名访问,不能通过包含类的实例访问。

    如果你有这样的课程:

    class MyClass {
        companion object {
            fun create() {}
        }
    }
    

    你可以像这样调用伴生对象的方法:

    MyClass.create()

    但不是这样的:

    new MyClass.create

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-31
      • 1970-01-01
      • 2019-06-02
      • 2021-12-15
      • 2016-05-21
      • 1970-01-01
      相关资源
      最近更新 更多