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á.

  • Modificar "esto" en la function de extensión
  • Crear nueva instancia de object Kotlin
  • Cómo acceder a una vista desde el layout especificado en headerLayout de NavigationView usando Kotlin en Android
  • Función de queue Kotlin List
  • Kotlin crea problemas con Android
  • findViewById ClassCastExcpetion
  • Kotlin: ¿Cómo ejecutar methods de service en el context de una class de transacción?
  • ¿Puedo enviar la function de extensión a través del parámetro de function?
  • Choque de extensión Kotlin
  • Kotlin class NoClassDefFoundError crash
  • Android Studio y Kotlin: reference no resuelta: también