Propiedad de extensión en línea Kotlin

Sé que la palabra key en línea significa evitar la sobrecarga de llamadas llamando a una function. Pero no puedo entender en qué línea funciona una propiedad de extensión.

Digamos que tenemos dos properties de extensión llamadas foo y otra con barra con nombre en línea

val Any.foo : Long get() = Date().time inline val Any.bar : Long get() = Date().time 

Ejecutando cualquiera de ellos, tenemos la salida esperada, la hora actual.

El bytecode para este file es el siguiente:

 public final class InlinedExtensionPropertyKt { public final static getFoo(Ljava/lang/Object;)J @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD 0 LDC "$receiver" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 9 L1 NEW java/util/Date DUP INVOKESPECIAL java/util/Date.<init> ()V INVOKEVIRTUAL java/util/Date.getTime ()J LRETURN L2 LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0 MAXSTACK = 2 MAXLOCALS = 1 public final static getBar(Ljava/lang/Object;)J @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD 0 LDC "$receiver" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 12 L1 NEW java/util/Date DUP INVOKESPECIAL java/util/Date.<init> ()V INVOKEVIRTUAL java/util/Date.getTime ()J LRETURN L2 LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0 LOCALVARIABLE $i$f$getBar I L0 L2 1 MAXSTACK = 2 MAXLOCALS = 2 @Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=2, d1={"\u0000\u000e\n\u0000\n\u0002\u0010\u0009\n\u0002\u0010\u0000\n\u0002\u0008\u0005\"\u0016\u0010\u0000\u001a\u00020\u0001*\u00020\u00028\u00c6\u0002\u00a2\u0006\u0006\u001a\u0004\u0008\u0003\u0010\u0004\"\u0015\u0010\u0005\u001a\u00020\u0001*\u00020\u00028F\u00a2\u0006\u0006\u001a\u0004\u0008\u0006\u0010\u0004\u00a8\u0006\u0007"}, d2={"bar", "", "", "getBar", "(Ljava/lang/Object;)J", "foo", "getFoo", "test sources for module app"}) // compiled from: InlinedExtensionPropertyKt.kt } 

Podemos ver que ambos son similares pero diferentes solo en estas líneas:

extracto de Foo :

  LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0 MAXSTACK = 2 MAXLOCALS = 1 

extracto de barra :

  LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0 LOCALVARIABLE $i$f$getBar I L0 L2 1 MAXSTACK = 2 MAXLOCALS = 2 

Realmente no entiendo lo que está pasando aquí. ¿Puede alguien señalarme para ver cuál es el comportamiento, o el equivalente en Java, o algún uso para esto?

Editar

Dado que el comstackdor replaceá el contenido de la propiedad en línea, puede convenir alinear cada propiedad de extensión que no tenga operaciones pesadas?

Gracias

Del documento de Kotlin ,

Tenga en count que, dado que las extensiones no insertan miembros en las classs, no existe una forma eficiente para que una propiedad de extensión tenga un campo de respaldo .

y también

El modificador en inline se puede usar en accesadores de properties que no tienen un campo de respaldo .

Como se mencionó anteriormente, una propiedad de extensión en línea no tiene un campo de respaldo. Puede tratar una propiedad de extensión como un par de getter / setter estático, como este:

 //In Kotlin var Any.foo : Long get() = Date().time set(value) { //Cannot access field here since extension property cannot have backing field //Do something with `obj` } //In Java public static long getFoo(Object obj) { return new Date().getTime(); } public static void setFoo(Object obj) { //Do something with `obj` } 

Por lo tanto, la propiedad en línea significa que el código de la function getter / setter se insertá en el sitio de llamadas cuando se accede a la propiedad (lo mismo que las funciones regulares en línea).

 //In Kotlin val x = "".foo val y = "".bar //Generated code val x = InlinedExtensionPropertyKt.getFoo("") val y = Date().time 

Para el bytecode que publicas en la pregunta, perdón por no poder explicar lo que está sucediendo. Pero puede intentar echar un vistazo al bytecode del siguiente código:

 fun get() { val x = "".foo val y = "".bar } 

, donde "".foo invocará la function getter pero "".bar no lo hará.

  • Genéricos para RecyclerView.Adapter Android
  • Kotlin: Cómo extender la class enum con una function de extensión
  • ¿Puedo enviar la function de extensión a través del parámetro de function?
  • ¿Cómo extiendo la class Kotlin Number o uso generics para crear un getter de propiedad simple que operará en todas las subclasss Number?
  • ¿Funciones de extensión Kotlin contra funciones miembro?
  • Establecer una extensión de kotlin
  • ¿Cómo se pueden agregar methods estáticos a las classs de Java en Kotlin?
  • Función de extensión booleana
  • Función de extensión Kotlin en propiedad mutable
  • Complemento de estudio Android con id: 'kotlin-android-extensions'
  • Funciones de extensión en types anotados