在最简单的情况下,VM是否跳过自动装箱?

问题描述 投票:0回答:1

[通过一个简单的通用接口进行实验,我发现Kotlin似乎总是使用Java原语来支持不可为空的变量,并且只将其放入getter中。 (使用IDEA的反编译功能)。如果创建的属性不是基于满足通用属性的,则没有装箱。所以这段代码:

interface Provider<T: Any> {
    val value: T
}

class WrappedInt(override val value: Int): Provider<Int>{
    val primitiveValue = value
}

基本编译为该Java代码:

public final class WrappedInt implements Provider {
   private final int value;
   private final int primitiveValue;

   public WrappedInt(int value) {
      this.value = value;
      this.primitiveValue = this.getValue();
   }

   @NotNull
   public Integer getValue() {
      return this.value;
   }

   public final int getPrimitiveValue() {
      return this.primitiveValue;
   }
}

我想知道的是,提供属性的原始副本是否会有任何价值,所以当通用接口无关紧要时,将有一个优化的吸气剂可用。还是VM足够聪明,可以跳过将直接变成原始变量或方程式的变量装箱?例如:

val variable = WrappedInt(5)
val result = variable.value * 5 // Did the backing field get boxed and immediately unboxed here?

我主要对Android的ART感兴趣,但也对JVM感兴趣。

注意,如果确实提供原始属性是有帮助的,则最好在类定义中交换两个属性,并为接口属性使用已定义的getter,这样就只有一个备用字段。我仅以这种方式保留了它,以说明无论getter返回盒装值如何,后备字段都是原始类型。

java android kotlin optimization jvm
1个回答
0
投票

自动装箱发生在编译时,而不是运行时。字节码:

val x = WrappedInt(5)
val y = x.value * 5
val z = x.primitiveValue * 5

显示y而不是z的方程式发生自动拆箱。因此,如果接口实现可能经常访问其备用值,则提供备用原始getter可能会有一些好处。

© www.soinside.com 2019 - 2024. All rights reserved.