【问题标题】:@file:JvmName vs @JvmStatic in companion object@file:JvmName 与伴随对象中的 @JvmStatic
【发布时间】:2019-08-05 08:57:47
【问题描述】:

我正在将部分应用程序从 Java 迁移到 Kotlin,对此有疑问。

什么是更可取或更好的方法?

  1. 内含注释@file:JvmName 和函数的文件
@file:JvmName("ClassX")

fun funX() {}

  1. 伴随对象内带有 @JvmStatic 注释的典型类
class ClassX {
    companion object {
        @JvmStatic
        fun funX() {}
    }
}

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    让我们看一下反编译的代码来回答这个问题。

    像你这样带有 @JvmName 注释的 Kotlin 文件:

    @file:JvmName("ClassX")
    
    fun funX() {}
    

    将被编译成字节码,类似于这段 Java 代码:

    @JvmName(
       name = "ClassX"
    )
    public final class ClassX {
       public static final void funX() {
       }
    }
    

    与您在使用 Java 时可能编写的内容非常相似,对吧?

    一个带有这样一个伴随对象的 Kotlin 类:

    class ClassX {
        companion object {
            @JvmStatic
            fun funX() {}
        }
    }
    

    类似于这段 Java 代码:

    public final class ClassX {
       public static final ClassX.Companion Companion = new ClassX.Companion((DefaultConstructorMarker)null);
    
       @JvmStatic
       public static final void funX() {
          Companion.funX();
       }
    
       public static final class Companion {
          @JvmStatic
          public final void funX() {
          }
    
          private Companion() {
          }
    
          // $FF: synthetic method
          public Companion(DefaultConstructorMarker $constructor_marker) {
             this();
          }
       }
    }
    

    如您所见,带有伴随对象的类会生成更多代码。

    是好是坏?你决定。我会说这很糟糕,最好使用带有 @JvmName 注释的文件。 Kotlin 的论坛也有关于这个话题的讨论:read the best practices.

    顺便说一句,您可以通过“工具”->“Kotlin”->“显示 Kotlin 字节码”查看 IntelliJ IDEA 中的字节码和反编译的 Java 代码。

    【讨论】:

    • 此外,它们在 Java 中的引用方式与 Kotlin 不同,在 Kotlin 中的推荐做法是使用顶级函数:stackoverflow.com/questions/54862918/…
    • 谢谢@AlexeyRomanov,我已将 Dmitry 在论坛上的声明链接到此处。
    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 2016-08-09
    • 2016-05-21
    • 1970-01-01
    • 2019-03-07
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多