【问题标题】:Does Kotlin generated byte code affect the method count?Kotlin 生成的字节码会影响方法计数吗?
【发布时间】:2019-03-29 15:35:41
【问题描述】:

例如,如果我使用

methodReference = ::method

而不是

methodReference = { method(it) }

由于反射,反编译的代码将在 Java 代码中包含 getOwnergetNamegetSignature 方法。这些方法是否计入 64k 限制?

【问题讨论】:

  • 是的,proguard/R8 不会删除它们
  • 我知道差别真的很小,但是这是否使传递 lambda 比方法引用更有效?
  • 完全没有区别,第一个会为方法引用(几个方法)生成一个对象,第二个——lambda
  • 谢谢!如果您添加答案,我会将其标记为已接受。

标签: java android kotlin


【解决方案1】:

仅当 proguard/R8 未删除方法时才计算方法

一个例子

  fun method(t : Any) {}
  val reference1: KFunction1<Any, Unit> = ::method
  val reference2: (Any) -> Unit = { method(it) }

对于reference1,字节码(反编译为 Java)为:

   @NotNull
   final KFunction reference1 = new Function1((X)this) {
      // $FF: synthetic method
      // $FF: bridge method
      public Object invoke(Object var1) {.. }
      public final void invoke(@NotNull Object p1) {..}
      public final KDeclarationContainer getOwner() {..}
      public final String getName() {..}
      public final String getSignature() {..}
   };

对于 lambda(或 reference2),等效的 java 代码是:

   @NotNull
   final Function1 reference2 = (Function1)(new Function1() {
      // $FF: synthetic method
      // $FF: bridge method
      public Object invoke(Object var1) {..}
      public final void invoke(@NotNull Object it) {..}
   });

所以区别是 4 +1 用于方法引用和 1 +1 用于 lambda,其中 +1 来自桥接方法 invoke(t:Any)

【讨论】:

  • 这似乎不再是问题了。在撰写本文时,Kotlin 1.6 已经发布,在反编译提供的示例时,我们在两种情况下都得到相同的字节码。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2015-08-01
  • 2017-09-24
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多