Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Kotlin Backstage - Android Makers Paris 2018

279 views

Published on

Kotlin offers a modern language design in contrast to Java, while at the same time maintaining full Java interoperably: Data classes, properties, delegation, inline functions, string interpolation and much more. But, if Java can't offer these features how come Kotlin can? What does Kotlin do to make it possible to use this Syntactic sugar?

In this talk, we will go backstage and dig into the Bytecode that Kotlin generates to make all the features we love work on a runtime that technically does not support them. We will look at the impact kotlin code generations has on method count. Get a deeper understanding of how Object and companion object work and see the implications of the use of either under different circumstances. Finally look at common patterns that can help reduce the size of both the bytecode and method count.

Published in: Technology
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Kotlin Backstage - Android Makers Paris 2018

  1. 1. Kotlin Backstage class GitApi( var client: GitApiService ) : GitApiService by client This code has a bug. What is it? Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  2. 2. private GitApi; client public final getClient()GitApi; GETFIELD GitService.client : GitApi; public final setClient(GitApi;)V PUTFIELD GitService.client : GitApi; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  3. 3. public <init>(GitApi;)V INVOKESPECIAL Object.<init> ()V PUTFIELD GitService.$$delegate_0 : GitApi; PUTFIELD GitService.client : GitApi; RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  4. 4. private final synthetic GitApi; $$delegate_0 public repos() List; GETFIELD GitService.$$delegate_0 : GitApi; INVOKEINTERFACE GitApi.repos ()List; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  5. 5. class GitApi( client: GitApiService ) : GitApiService by client // OR class GitApi( private val client: GitApiService ) : GitApiService by client Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  6. 6. Kotlin Backstage • More Kotlin generated bytecode • Lambdas • Objects & Statics • Impact of const • Impact of Scoping on Method Count • A Glimpse into Coroutines Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  7. 7. Primitives val number: Int = 10 val number: Int? = 10 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  8. 8. Primitives private final static I number = 10 private final static Integer; nullableNumber Nullable;() // invisible Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  9. 9. String Interpolation val i = 10 val s = "i = $i" // evaluates to "i = 10" Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  10. 10. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (String;)StringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)StringBuilder; INVOKEVIRTUAL StringBuilder.toString ()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  11. 11. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (String;)StringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)StringBuilder; INVOKEVIRTUAL StringBuilder.toString ()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  12. 12. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (String;)StringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)StringBuilder; INVOKEVIRTUAL StringBuilder.toString ()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  13. 13. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (String;)StringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)StringBuilder; INVOKEVIRTUAL StringBuilder.toString ()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  14. 14. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (String;)StringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)StringBuilder; INVOKEVIRTUAL StringBuilder.toString ()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  15. 15. Classes class Speaker(val talk: String) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  16. 16. Classes public final class Speaker { private final String; talk @NotNull;() // invisible public final getTalk()String; @NotNull;() // invisible GETFIELD Speaker.talk : String; ARETURN public <init>(String;)V … PUTFIELD Speaker.talk : String; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  17. 17. Classes class Speaker(@JvmField val talk: String) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  18. 18. Classes public final class Speaker { public final String; talk @JvmField;() // invisible @NotNull;() // invisible public <init>(String;)V { … } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  19. 19. Nulls fun len(str: String) = str.length Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  20. 20. Nulls fun len(str: String) = str.length public final static len(String;)I @NotNull;() // invisible, parameter 0 ALOAD 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull ( Object;String; )V INVOKEVIRTUAL String.length ()I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  21. 21. Nulls fun len(str: String) = str.length public final static len(String;)I @NotNull;() // invisible, parameter 0 ALOAD 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull ( Object;String; )V INVOKEVIRTUAL String.length ()I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  22. 22. Nulls fun len(str: String) = str.length public final static len(String;)I @NotNull;() // invisible, parameter 0 ALOAD 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull ( Object;String; )V INVOKEVIRTUAL String.length ()I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  23. 23. Nulls fun len(str: String) = str.length public final static len(String;)I @NotNull;() // invisible, parameter 0 ALOAD 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull ( Object;String; )V INVOKEVIRTUAL String.length ()I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  24. 24. Nulls fun len(str: String) = str.length public final static len(String;)I @NotNull;() // invisible, parameter 0 ALOAD 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull ( Object;String; )V INVOKEVIRTUAL String.length ()I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  25. 25. Nulls fun maybeLen(str: String?): Int = str?.length ?: 0 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  26. 26. No-Nulls public final static maybeLen(String;)I Nullable;() // invisible, parameter 0 ALOAD 0 DUP IFNULL L1 INVOKEVIRTUAL String.length ()I GOTO L2 L1 POP ICONST_0 L2 IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  27. 27. No-Nulls public final static maybeLen(String;)I Nullable;() // invisible, parameter 0 ALOAD 0 DUP IFNULL L1 INVOKEVIRTUAL String.length ()I GOTO L2 L1 POP ICONST_0 L2 IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  28. 28. No-Nulls public final static maybeLen(String;)I Nullable;() // invisible, parameter 0 ALOAD 0 DUP IFNULL L1 INVOKEVIRTUAL String.length ()I GOTO L2 L1 POP ICONST_0 L2 IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  29. 29. fun Context.color(@ColorRes color: Int) = ContextCompat.getColor(this, color) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  30. 30. public static int color( Context $receiver, @ColorRes int color ) { return ContextCompat .getColor($receiver, color) } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  31. 31. public final static color(Context;I)I @NotNull;() // invisible, parameter 0 @ColorRes;() // invisible, parameter 1 ALOAD 0 LDC "$receiver" INVOKESTATIC checkParameterIsNotNull (Object; String;)V ALOAD 0 ILOAD 1 INVOKESTATIC ContextCompat.getColor (Context;I)I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  32. 32. public final static color(Context;I)I @NotNull;() // invisible, parameter 0 @ColorRes;() // invisible, parameter 1 ALOAD 0 LDC "$receiver" INVOKESTATIC checkParameterIsNotNull (Object; String;)V ALOAD 0 ILOAD 1 INVOKESTATIC ContextCompat.getColor (Context;I)I IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  33. 33. Inline fun inline fun inlineFun(func: () -> Unit) { before() func() after() } inlineFun { inlined() } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  34. 34. Inline fun public final inlineFun(Function0;)V @NotNull;() // invisible, parameter 0 INVOKEVIRTUAL InlineFuns.before ()V ALOAD 1 INVOKEINTERFACE Function0.invoke () INVOKEVIRTUAL InlineFuns.after ()V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  35. 35. Inline fun public final inlineFun(Function0;)V @NotNull;() // invisible, parameter 0 INVOKEVIRTUAL InlineFuns.before ()V ALOAD 1 INVOKEINTERFACE Function0.invoke () INVOKEVIRTUAL InlineFuns.after ()V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  36. 36. Inline fun inlineFun { inlined() } INVOKEVIRTUAL InlineFuns.before ()V INVOKEVIRTUAL InlineFuns.inlined ()V INVOKEVIRTUAL InlineFuns.after ()V Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  37. 37. Inline fun inlineFun { inlined() } INVOKEVIRTUAL InlineFuns.before ()V INVOKEVIRTUAL InlineFuns.inlined ()V INVOKEVIRTUAL InlineFuns.after ()V Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  38. 38. Kotlin Collections Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  39. 39. val numbers = arrayOf(0, 1, 2, 3, 4, 5) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  40. 40. val numbers = arrayOf(0, 1, 2, 3, 4, 5) BIPUSH 6 ANEWARRAY Integer INVOKESTATIC Integer.valueOf (I) Integer; // 4 more times INVOKESTATIC Integer.valueOf (I) Integer; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  41. 41. val numbers = intArrayOf(0, 1, 2, 3, 4, 5) BIPUSH 6 NEWARRAY T_INT ICONST_0 // Boilerplate bytecode, then repeat 4x more ICONST_5 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  42. 42. class Maper { fun twoX(x: Int) = x * 2 fun isEven(x: Int) = x % 2 == 0 } numbers.map(::twoX) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  43. 43. int[] $receiver$iv = this.numbers; Maper var2 = this; int[] $receiver$iv$iv = $receiver$iv; Collection destination$iv$iv = (Collection) (new ArrayList($receiver$iv.length)); int var5 = $receiver$iv.length; for(int var6 = 0; var6 < var5; ++var6) { int item$iv$iv = $receiver$iv$iv[var6]; Integer var13 = ((Maper)var2).twoX(item$iv$iv); destination$iv$iv.add(var13); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  44. 44. int len = numbers.length; Collection mappedNumbers = ArrayList(len) for(int i = 0; i < len; ++i) { int item = numbers[i]; Integer iItem = twoX(item); mappedNumbers.add(iItem); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  45. 45. int len = numbers.length; Collection mappedNumbers = ArrayList(len) for(int i = 0; i < len; ++i) { int item = numbers[i]; Integer iItem = twoX(item); mappedNumbers.add(iItem); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  46. 46. public interface IntMapper { int invoke(int x); } numbers.intMap ( IntMapper { it * 2} ) fun IntArray.intMap(f: IntMapper): IntArray { val len = this.size val result = IntArray(len) forEachIndexed { index, x -> result[index] = f(x) } return result } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  47. 47. intArrayOf(0, 1, 2, 3, 4, 5) .filter(::isEven) .map(::twoX) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  48. 48. Collection filtered = new ArrayList(); for(int i = 0; i < len; ++i) { int item = numbers[i]; if (isEven(item)) { filtered.add(item); } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  49. 49. Collection mapped = new ArrayList( collectionSizeOrDefault(filtered, 10) ); Iterator iter = filtered.iterator(); while(iter.hasNext()) { Object item = iter.next(); int next = ((Number)item).intValue(); Integer result = twoX(next); mapped.add(result); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  50. 50. intArrayOf(0, 1, 2, 3, 4, 5) .filter(::isEven) .map(::twoX) for(int i = 0; i < len; ++i) { int item = numbers[i]; if (isEven(item)) { filtered.add(element$iv$iv); } } while(iter.hasNext()) { Object item = iter.next(); int next = ((Number)item).intValue(); Integer result = twoX(next); mapped.add(result); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  51. 51. intArrayOf(0, 1, 2, 3, 4, 5) .asSequence() .filter(::isEven) .map(::twoX) .toList() Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  52. 52. GETFIELD Maper.numbers : [I INVOKESTATIC ArraysKt.asSequence ([I)Sequence; NEW Maper$1 // ::isEven INVOKESTATIC SequencesKt.filter (Sequence;Function1;) NEW Maper$2 // ::twoX INVOKESTATIC SequencesKt.map (Sequence;Function1;) INVOKESTATIC SequencesKt.toList (Sequence;)List; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  53. 53. GETFIELD Maper.numbers : [I INVOKESTATIC ArraysKt.asSequence ([I)Sequence; NEW Maper$1 // ::isEven INVOKESTATIC SequencesKt.filter (Sequence;Function1;) NEW Maper$2 // ::twoX INVOKESTATIC SequencesKt.map (Sequence;Function1;) INVOKESTATIC SequencesKt.toList (Sequence;)List; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  54. 54. final class Mapper$1 extends FunctionReference implements Function1 public synthetic bridge invoke(Object;) Object; public final invoke(I)Z // Z = Boolean <init>(Maper;)V public final getOwner()KDeclarationContainer; public final getName()String; public final getSignature()String; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  55. 55. final class Mapper$1 extends FunctionReference implements Function1 <init>(Maper;)V ALOAD 0 ICONST_1 ALOAD 1 INVOKESPECIAL FunctionReference.<init> (I;Object;)V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  56. 56. final class Mapper$1 extends FunctionReference implements Function1 <init>(Maper;)V ALOAD 0 ICONST_1 ALOAD 1 INVOKESPECIAL FunctionReference.<init> (I;Object;)V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  57. 57. public synthetic bridge invoke(Object;)Object; CHECKCAST Number INVOKEVIRTUAL Number.intValue ()I INVOKEVIRTUAL Maper$1.invoke (I)Z INVOKESTATIC Boolean.valueOf (Z)Boolean; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  58. 58. public final invoke(I)Z GETFIELD Maper$1.receiver : Object; INVOKEVIRTUAL Maper.isEven (I)Z IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  59. 59. public final getOwner()KDeclarationContainer; LDC Maper;.class INVOKESTATIC Reflection .getOrCreateKotlinClass (Class;)KClass; ARETURN public final getName()String; LDC "isEven" ARETURN public final getSignature()String; LDC "isEven(I)Z" ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  60. 60. class Maper { fun twoX(x: Int) = x * 2 fun isEven(x: Int) = x % 2 == 0 } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  61. 61. class Maper { private fun twoX(x: Int) = x * 2 private fun isEven(x: Int) = x % 2 == 0 } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  62. 62. // Mapper public final static synthetic access$isEven(Maper;I)Z // Mapper$1 public final invoke(I)Z INVOKEVIRTUAL Maper.access$isEven (I)Z Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  63. 63. intArrayOf(0, 1, 2, 3, 4, 5) .asSequence() .filter(::isEven) .map(::twoX) .toList() Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  64. 64. intArrayOf(0, 1, 2, 3, 4, 5) .asSequence() .filter { it % 2 == 0 } .map { it * 2} .toList() Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  65. 65. final class Maper$2 extends Lambda implements Function1 { public synthetic bridge invoke(Object;)Object; public final invoke(I)I <init>()V static <clinit>()V } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  66. 66. public synthetic bridge invoke(Object;) Object; CHECKCAST Number INVOKEVIRTUAL Number.intValue ()I INVOKEVIRTUAL Lmds$times2$1.invoke (I)I INVOKESTATIC Integer.valueOf (I)LInteger; ARETURN public final invoke(I)I ILOAD 1 ICONST_2 IMUL IRETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  67. 67. final class Maper$2 OUTERCLASS Maper <init> ()V final static INNERCLASS Maper$2 null null } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  68. 68. <init>()V ALOAD 0 ICONST_1 // Lambda arity INVOKESPECIAL Lambda.<init> (I)V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  69. 69. public final static Maper$2; INSTANCE static <clinit>()V NEW Maper$2 DUP INVOKESPECIAL Maper$2.<init> ()V PUTSTATIC Maper$2.INSTANCE : Maper$2; RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  70. 70. final class Maper$2 extends Lambda implements Function1 { public synthetic bridge invoke(Object;)Object; public final invoke(I)I public final static LMaper$2; INSTANCE <init>()V static <clinit>()V OUTERCLASS Maper <init> ()V final static INNERCLASS Maper$2 null null } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  71. 71. numbers .asSequence() .filter { it % 2 == 0} .map { it * 2} .toList() Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  72. 72. GETFIELD Maper.numbers : [I INVOKESTATIC ArraysKt .asSequence ([I)Sequence; GETSTATIC Maper$1.INSTANCE : LMaper$1; INVOKESTATIC SequencesKt .filter (Sequence;Function1;)Sequence; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  73. 73. GETFIELD Maper.numbers : [I INVOKESTATIC ArraysKt .asSequence ([I)Sequence; GETSTATIC Maper$1.INSTANCE : LMaper$1; INVOKESTATIC SequencesKt .filter (Sequence;Function1;)Sequence; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  74. 74. Reduce Lambda Method? • Synthetic bridge is cause type erasure • Static Constructor is casue of re-use Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  75. 75. Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  76. 76. SAMs view.setOnClickListener { print("Hello") } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  77. 77. final class Sam$1 implements View$OnClickListener { public final static Sam$1; INSTANCE public final onClick(View)V; <init>()V; static <clinit>()V NEW Sam$1 INVOKESPECIAL Sam$1.<init> ()V PUTSTATIC Sam$1.INSTANCE : Sam$1; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  78. 78. final class Sam$1 implements View$OnClickListener { public final onClick(View;)V <init>(I)V PUTFIELD MainActivity$onCreate$1.$x : I INVOKESPECIAL Object.<init> ()V RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  79. 79. class Lmd ( private val speaker: Speaker ) { private val lambda = { speaker.name } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  80. 80. final class Lmd$lambda$1 { final synthetic Lmd; this$0 public final invoke()String; GETFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker; INVOKEVIRTUAL Speaker.getName ()String; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  81. 81. final class Lmd$lambda$1 { final synthetic Lmd; this$0 public final invoke()String; GETFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker; INVOKEVIRTUAL Speaker.getName ()String; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  82. 82. public final class Lmd { public final static synthetic access$getSpeaker$p(Lmd;)Speaker; ALOAD 0 GETFIELD Lmd.speaker : Speaker; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  83. 83. class Lmd ( @JvmField protected val speaker: Speaker ){ private val lambda = { speaker.name } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  84. 84. class Lmd ( @Suppress("ProtectedInFinal") @JvmField protected val speaker: Speaker ){ private val lambda = { speaker.name } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  85. 85. final class Lmd$lambda$1 { public final invoke()String; GETFIELD Lmd$lambda$1.this$0 : Lmd; GETFIELD Lmd.speaker : Speaker; INVOKEINTERFACE Speaker.getName () String; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  86. 86. Data Classes data class Speaker( val description: String, val profile: String, val talks: List<Talk> ) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  87. 87. val speaker = Speaker( description = "Bytecode", profile = "", talks = arrayListOf() ) val (description, _, talks) = speaker Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  88. 88. public final component1()String; GETFIELD Speaker.description : String; public final component2()String; GETFIELD Speaker.profile : String; public final component3()List; GETFIELD Speaker.talks : List; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  89. 89. val (description, talks) = speaker // "Variable name 'talks' matches // the name of a different component" Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  90. 90. val (description, talks) = speaker inspect project-path inspection-path output-path [-vX] [-d subdirectory-path] Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  91. 91. public final copy(String;List;)LSpeaker; NEW Speaker INVOKESPECIAL Speaker.<init> (String;String;List;)V ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  92. 92. val speaker2 = speaker.copy( description = "Second speaker" ) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  93. 93. GETFIELD Copy.speaker LDC "Second speaker" ACONST_NULL ACONST_NULL BIPUSH 6 ACONST_NULL INVOKESTATIC Speaker.copy$default ( Speaker; String; String; List; I; Object; )Speaker; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  94. 94. GETFIELD Copy.speaker LDC "Second speaker" ACONST_NULL ACONST_NULL BIPUSH 6 ACONST_NULL INVOKESTATIC Speaker.copy$default ( Speaker; String; String; List; I; Object; )Speaker; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  95. 95. GETFIELD Copy.speaker LDC "Second speaker" ACONST_NULL ACONST_NULL BIPUSH 6 ACONST_NULL INVOKESTATIC Speaker.copy$default ( Speaker; String; String; List; I; Object; )Speaker; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  96. 96. BIPUSH 6 ACONST_NULL INVOKESTATIC Speaker.copy$default ( Speaker; String; String; List; I; Object; )Speaker; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  97. 97. public static synthetic bridge copy$default( Speaker; String; String; List; I; Object; ) Speaker; ILOAD 4 ICONST_1 IAND IFEQ L0 ALOAD 0 GETFIELD Speaker.description : String; ASTORE 1 L0 ILOAD 4 ICONST_2 IAND IFEQ L1 ALOAD 0 GETFIELD Speaker.profile : String; ASTORE 2 L1 ILOAD 4 ICONST_4 IAND IFEQ L2 ALOAD 0 GETFIELD Speaker.talks : List; ASTORE 3 L2 ALOAD 0 ALOAD 1 ALOAD 2 ALOAD 3 INVOKEVIRTUAL Speaker.copy (String;String;List;)Speaker; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  98. 98. public static Speaker copy$default( Speaker var0, String var1, String var2, List var3, int var4, Object var5 ) { if ((var4 & 1) != 0) { var1 = var0.description; } if ((var4 & 2) != 0) { var2 = var0.profile; } if ((var4 & 4) != 0) { var3 = var0.talks; } return var0.copy(var1, var2, var3); } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  99. 99. public static Speaker copy$default( Speaker sourceSpeaker, String description, String profile, List talks, int hash, Object arityMarker ) { // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  100. 100. public static Speaker copy$default( Speaker sourceSpeaker, String description, String profile, List talks, int hash, Object arityMarker ) { // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  101. 101. public static Speaker copy$default( Speaker sourceSpeaker, String description, String profile, List talks, int hash, Object arityMarker ) { // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  102. 102. public static Speaker copy$default( Speaker sourceSpeaker, String description, String profile, List talks, int hash, Object arityMarker ) { // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  103. 103. if ((hash & 1) != 0) description = sourceSpeaker.description; if ((hash & 2) != 0) profile = sourceSpeaker.profile; if ((hash & 4) != 0) talks = sourceSpeaker.talks; return sourceSpeaker .copy(description, profile, talks); Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  104. 104. Static's Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  105. 105. private val speaker = Speaker() Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  106. 106. public final class ObjectsKt { private final static Speaker; speaker static <clinit>()V NEW Speaker DUP INVOKESPECIAL Speaker.<init> ()V PUTSTATIC ObjectsKt.speaker : LSpeaker; RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  107. 107. public final class ObjectsKt { private final static Speaker; speaker static <clinit>()V NEW Speaker DUP INVOKESPECIAL Speaker.<init> ()V PUTSTATIC ObjectsKt.speaker : LSpeaker; RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  108. 108. fun someStr() = "Some String" public final class ObjectsKt { public final static someStr() String; LDC "Some String" ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  109. 109. fun someStr() = "Some String" public final class ObjectsKt { public final static someStr() String; LDC "Some String" ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  110. 110. private val someStr = "Some String" public final class ObjectsKt { private final static String; someStr = "Some String" static <clinit>()V LDC "Some String" PUTSTATIC ObjectsKt.someStr : String; RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  111. 111. private val someStr = "Some String" public final class ObjectsKt { private final static String; someStr = "Some String" static <clinit>()V LDC "Some String" PUTSTATIC ObjectsKt.someStr : String; RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  112. 112. private val someStr = "Some String" public final class ObjectsKt { private final static String; someStr = "Some String" static <clinit>()V LDC "Some String" PUTSTATIC ObjectsKt.someStr : String; RETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  113. 113. private const val someStr = "Some String" public final class ObjectsKt { private final static String; someStr = "Some String" } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  114. 114. private const val someStr = "Some String" public final class ObjectsKt { private final static String; someStr = "Some String" } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  115. 115. Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  116. 116. object AnObject public final class AnObject { public final static AnObject; INSTANCE private <init>()V static <clinit>()V INVOKESPECIAL AnObject.<init> ()V PUTSTATIC AnObject.INSTANCE : AnObject; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  117. 117. object AnObject public final class AnObject { public final static AnObject; INSTANCE private <init>()V static <clinit>()V INVOKESPECIAL AnObject.<init> ()V PUTSTATIC AnObject.INSTANCE : AnObject; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  118. 118. object AnObject { val name = "Mitchell" } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  119. 119. public final class AnObject { private final static String; name = "Mitchell" public final getName()String; static <clinit>()V LDC "Mitchell" PUTSTATIC AnObject.name : String; RETURN private <init>()V public final static AnObject; INSTANCE } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  120. 120. object AnObject { const val name = "Mitchell" } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  121. 121. public final class AnObject { public final static String; name = "Mitchell" public final static AnObject; INSTANCE private <init>()V static <clinit>()V NEW AnObject DUP INVOKESPECIAL AnObject.<init> ()V PUTSTATIC AnObject.INSTANCE : AnObject; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  122. 122. object AnObject { fun speaker() = Speaker() } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  123. 123. public final class AnObject { public final speaker() Speaker; NEW Speaker DUP INVOKESPECIAL Speaker.<init> ()V ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  124. 124. object AnObject { @JvmStatic fun speaker() = Speaker() } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  125. 125. public final class AnObject { public final static speaker() Speaker; @JvmStatic;() @NotNull;() // invisible } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  126. 126. Companion Object Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  127. 127. class TopicFragment { companion object { } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  128. 128. public final class TopicFragment { public <init>()V static <clinit>()V public final static TopicFragment$Companion; Companion } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  129. 129. public final class TopicFragment { static <clinit>()V NEW TopicFragment$Companion ACONST_NULL INVOKESPECIAL TopicFragment$Companion.<init> ( DefaultConstructorMarker; )V PUTSTATIC TopicFragment.Companion : TopicFragment$Companion; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  130. 130. public final class TopicFragment { static <clinit>()V NEW TopicFragment$Companion ACONST_NULL INVOKESPECIAL TopicFragment$Companion.<init> ( DefaultConstructorMarker; )V PUTSTATIC TopicFragment.Companion : TopicFragment$Companion; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  131. 131. public final class TopicFragment$Companion { private <init>()V public synthetic <init>(…Marker;)V INVOKESPECIAL TopicFragment$Companion.<init> ()V } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  132. 132. class TopicFragment { companion object { val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  133. 133. class TopicFragment { init { EXTRA_TOPIC_ID } companion object { val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  134. 134. public final class TopicFragment { private final static String; EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" // Why is it privte? } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  135. 135. public final class TopicFragment { static <clinit>()V NEW TopicFragment$Companion LDC "EXTRA_TOPIC_ID" PUTSTATIC TopicFragment .EXTRA_TOPIC_ID : String; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  136. 136. public final class TopicFragment { // Kotlin 1.2.31- public <init>()V GETSTATIC Companion : $Companion; INVOKEVIRTUAL $Companion .getEXTRA_TOPIC_ID ()String; // Kotlin 1.2.40+ ! public <init>()V GETSTATIC TopicFragment.EXTRA_TOPIC_ID : String; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  137. 137. public final class TopicFragment$Companion { fun newInstance() { val bundle = Bundle() bundle.putLong(EXTRA_TOPIC_ID, 1) } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  138. 138. public final newInstance()V NEW android/os/Bundle INVOKEVIRTUAL TopicFragment$Companion .getEXTRA_TOPIC_ID ()String; LCONST_1 INVOKEVIRTUAL Bundle.putLong (String; J)V RETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  139. 139. public final class TopicFragment$Companion { public final getEXTRA_TOPIC_ID()String; INVOKESTATIC TopicFragment .access$getEXTRA_TOPIC_ID$cp ()String; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  140. 140. public final class TopicFragment { public final static synthetic access$getEXTRA_TOPIC_ID$cp() GETSTATIC TopicFragment .EXTRA_TOPIC_ID : String; ARETURN } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  141. 141. Kotlin 1.2.31- Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  142. 142. class TopicFragment { init { EXTRA_TOPIC_ID } companion object { const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  143. 143. public final class TopicFragment { public final static String; EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" public <init>()V static <clinit>()V } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  144. 144. class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { companion object { private val FORMATTER: DateTimeFormatter = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss") fun parseDateString(dateString: String?) : LocalDateTime = LocalDateTime.parse(dateString, FORMATTER) } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  145. 145. class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { private final static DateTimeFormatter; FORMATTER public final static synthetic access$getFORMATTER$cp() } LocalDateTimeAdapter$Companion { public final parseDateString(String;)LocalDateTime; INVOKESTATIC LocalDateTimeAdapter .access$getFORMATTER$cp () } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  146. 146. class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { private final static DateTimeFormatter; FORMATTER public final static synthetic access$getFORMATTER$cp() } LocalDateTimeAdapter$Companion { public final parseDateString(String;)LocalDateTime; INVOKESTATIC LocalDateTimeAdapter .access$getFORMATTER$cp () } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  147. 147. class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { companion object { private val FORMATTER: DateTimeFormatter = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss") fun parseDateString(dateString: String?) : LocalDateTime = LocalDateTime.parse(dateString, FORMATTER) } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  148. 148. private object FormatCompanion { @JvmField val FORMATTER: DateTimeFormatter = DateTimeFormatter .ofPattern("yyyy-MM-dd'T'HH:mm:ss") } class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  149. 149. final class FormatCompanion { public final static DateTimeFormatter; FORMATTER } public final class LocalDateTimeAdapter$Companion { public final parseDateString(String;)LocalDateTime; GETSTATIC FormatCompanion.FORMATTER // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  150. 150. final class FormatCompanion { public final static DateTimeFormatter; FORMATTER } public final class LocalDateTimeAdapter$Companion { public final parseDateString(String;)LocalDateTime; GETSTATIC FormatCompanion.FORMATTER // … } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  151. 151. companion object { private const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" fun newInstance(topicId: Int) { val args = Bundle().apply { // LDC "EXTRA_TOPIC_ID" putInt(EXTRA_TOPIC_ID, topicId) } return TopicFragment().apply { arguments = args } } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  152. 152. companion object { private const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" fun newInstance(topicId: Int) { val args = Bundle().apply { // LDC "EXTRA_TOPIC_ID" putInt(EXTRA_TOPIC_ID, topicId) } return TopicFragment().apply { arguments = args } } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  153. 153. Reducing Synthetic Methods Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  154. 154. class TopicDetailViewModel @Inject constructor( private val repository: SessionRepository, private val schedulerProvider: SchedulerProvider ) : ViewModel() { val topicSessions: LiveDataSessions by lazy { repository.topicSessions .map(…) .toResult(schedulerProvider) .toLiveData() } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  155. 155. public final class TopicDetailViewModel extends ViewModel { public final static synthetic access$getRepository$p( TopicDetailViewModel; )SessionRepository; public final static synthetic access$getScheduler Provider$p( TopicDetailViewModel; )SchedulerProvider; } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  156. 156. class TopicDetailViewModel @Inject constructor( private val repository: SessionRepository, private val schedulerProvider: SchedulerProvider ) : ViewModel() { val topicSessions: LiveDataSessions by lazy { repository.topicSessions .map(…) .toResult(schedulerProvider) .toLiveData() } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  157. 157. class TopicDetailViewModel @Inject constructor( @JvmField protected val repository: SessionRepository, @JvmField protected val schedulerProvider: SchedulerProvider ) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  158. 158. @Suppress("ProtectedInFinal") class TopicDetailViewModel @Inject constructor( @JvmField protected val repository: SessionRepository, @JvmField protected val schedulerProvider: SchedulerProvider ) Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  159. 159. Async Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  160. 160. class Async { suspend fun waitFor(x: Int): Int { delay(x) return x } } Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  161. 161. suspend fun waitFor(x: Int): Int public final waitFor(I; Continuation;) Object; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  162. 162. public final waitFor(I; Continuation;) Object; INSTANCEOF Async$waitFor$1 IFEQ L0 CHECKCAST Async$waitFor$1 INVOKEVIRTUAL Async$waitFor$1.getLabel ()I IFEQ L0 INVOKEVIRTUAL Async$waitFor$1.getLabel ()I INVOKEVIRTUAL Async$waitFor$1.setLabel (I)V GOTO L1 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  163. 163. public final waitFor(I; Continuation;) Object; L0 // create new state machine NEW Async$waitFor$1 INVOKESPECIAL Async$waitFor$1.<init> (Continuation;)V L1 // Resume state machine GETFIELD Async$waitFor$1.data : Object; GETFIELD Async$waitFor$1.exception : Throwable; INVOKESTATIC IntrinsicsKt.getCOROUTINE_SUSPENDED ()Object; Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  164. 164. public final waitFor(I; Continuation;) Object; L2 INVOKEVIRTUAL Async$waitFor$1.getLabel ()I TABLESWITCH 0: L3 1: L4 default: L5 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  165. 165. public final waitFor(I; Continuation;) Object; L3 ALOAD 4 DUP IFNULL L6 ATHROW // bunch of state management ICONST_1 INVOKEVIRTUAL Async$waitFor$1.setLabel (I)V INVOKESTATIC DelayKt.delay (I; Continuation;)Object; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  166. 166. public final waitFor(I; Continuation;) Object; L3 ALOAD 4 DUP IFNULL L6 ATHROW // bunch of state management ICONST_1 INVOKEVIRTUAL Async$waitFor$1.setLabel (I)V INVOKESTATIC DelayKt.delay (I; Continuation;)Object; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  167. 167. public final waitFor(I; Continuation;) Object; L3 ALOAD 4 DUP IFNULL L6 ATHROW // bunch of state management ICONST_1 INVOKEVIRTUAL Async$waitFor$1.setLabel (I)V INVOKESTATIC DelayKt.delay (I; Continuation;)Object; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  168. 168. public final waitFor(I; Continuation;) Object; INVOKEVIRTUAL Async$waitFor$1.getLabel ()I TABLESWITCH 0: L3 1: L4 default: L5 Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  169. 169. public final waitFor(I; Continuation;)Object; L4 GETFIELD Async$waitFor$1.I$0 : I GETFIELD Async$waitFor$1.L$0 : Object; CHECKCAST tilbrook/com/au/kotlinbackstage/Async IFNULL L12 ATHROW Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  170. 170. suspend fun waitFor(x: Int): Int { return x } public final waitFor(I; Continuation;)Object; L4 ILOAD 1 INVOKESTATIC Integer.valueOf (I)Integer; ARETURN Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  171. 171. Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  172. 172. Bytecode Viewer https://github.com/borisf/classyshark-bytecode-viewer Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders
  173. 173. Mitchell Tilbrook @sir_tilbrook Sydney Tech Talks youtube.com/c/anzcoders Moneytree Android Developer moneytree.jp Mitchell Tilbook: @sir_tilbrook Sydney Tech Meetups: youtube.com/c/anzcoders

×