【问题标题】:Kotlin static functions : companion object, @JvmStatic @JvmFieldKotlin 静态函数:伴生对象,@JvmStatic @JvmField
【发布时间】:2018-06-21 20:36:42
【问题描述】:

我刚刚开始使用 Kotlin 编程语言,它比 Java 酷得多。我对静态方法和字段有一些疑问:

Q1:官方文档说

Kotlin 还可以为命名中定义的函数生成静态方法 对象或伴随对象,如果您将这些函数注释为 @JvmStatic。

但是,如果您在下面看到,我可以将 bar() 方法作为静态方法访问,该方法无需使用 @JvmStatic 注释即可工作。但是在官方文档上它的抛出错误-> Kotlin static method.

Class C{
    companion object{
        @JvmStatic
        fun foo() { }
        fun bar();
    }
}
fun main(args: Array<String>) {
    C.foo();
    C.bar(); //this line works fine
}

Q2:我真的需要@JvmStatic@JvmField 来使事情静态化吗? 正如您在 companion 对象中看到的那样,一切正常。

【问题讨论】:

  • @user8371915 我已经删除了代码的图像。谢谢

标签: android static kotlin


【解决方案1】:

您可以以C.bar() 在 Kotlin 中访问 companion object 的成员,但在 Java 中则不行。如果没有 @JvmStatic,您将需要在 在 Java 中 使用 C.Companion.bar(),就像文档中所说的那样。

请注意,如果没有 @JvmStatic,该函数将编译为在 Java 中在 C.Companion 上调用的实例(非静态)方法(Kotlin 只是将其缩短为在 C 上的调用,但它是引擎盖下相同),所以是的,您需要 @JvmStatic@JvmField 在伴随对象中进行声明编译成静态成员。

基本上,@JvmStatic@JvmField 是 Java 互操作工具,有助于创建对 Java 友好的 API,如果您不需要从 Java 调用 Kotlin 成员(例如,它们在您的 Kotlin 项目内部,或者您正在开发一个不太可能与 Java 一起使用的库),您可以保持原样。

【讨论】:

  • 现在我明白了。谢谢。
  • 您知道使用@JvmStatic@JvmField 时生成的Java 代码是否有任何不同?
  • @Joschua,对于@JvmStatic,属性访问器将变为静态,但@JvmField 将改为公开静态支持字段并指示编译器根本不生成访问器。另请注意,@JvmField 适用于实例属性,然后将其编译为非静态字段。
【解决方案2】:

是的,您确实需要@JvmStatic在 Kotlin 中 而在文档代码中称为 在 Java 中的代码问题。

更准确地说,这段代码不会编译:

public void main(String[] args) {
    C.foo(); // Ok
    C.bar(); // Not ok
}

Kotlin 知道 companion object 中的函数,因此您可以直接在类上调用它,而 Java 对此一无所知。所以你用@JvmStatic注释任何函数,它就会作为静态方法在Java代码中可见。

只是为了澄清 - @JvmStatic 的目的是与 Java 代码互操作。如果您只使用 Kotlin 编写应用程序,则根本不需要 @JvmStatic

【讨论】:

    【解决方案3】:

    文档(“第 2 页”)指的是从 Java 而非 Kotlin 调用函数的情况。

    当你只使用 Kotlin 时,不需要注解。而是使用您声明 bar() 方法的方式。所以你可以拨打C.bar()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2020-01-18
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多