SlideShare a Scribd company logo
1 of 99
Download to read offline
Kotlin Backstage
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Kotlin Backstage
— What Kotlin generates in bytecode
— Impact of const
— Objects & Statics
— Impact of Scoping on method count
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Primitives
val number: Int = 10
val number: Int? = 10
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Primitives
private final static I number = 10
private final static L…/Integer; nullableNumber
@L…/Nullable;() // invisible
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
String Interpolation
val i = 10
val s = "i = $i" // evaluates to "i = 10"
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
String Interpolation
NEW StringBuilder
DUP
INVOKESPECIAL StringBuilder.<init> ()V
LDC "i = "
INVOKEVIRTUAL StringBuilder.append (LString;)LStringBuilder;
GETSTATIC ExtKt.i : I
INVOKEVIRTUAL StringBuilder.append (I)LStringBuilder;
INVOKEVIRTUAL StringBuilder.toString ()LString;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Classes
class Speaker(val talk: String)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
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
youtube.com/c/anzcoders
Classes
class Speaker(@JvmField val talk: String)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Classes
public final class Speaker {
public final String; talk
@JvmField;() // invisible
@NotNull;() // invisible
public <init>(String;)V { … }
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Nulls
fun len(str: String) = str.length
fun maybeLen(str: String?) = str?.length ?: 0
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
No-Nulls
public final static len(String;)I
@NotNull;() // invisible, parameter 0
LDC "str"
INVOKESTATIC Intrinsics.checkParameterIsNotNull (Object;String;)V
INVOKEVIRTUAL String.length ()I
IRETURN
public final static maybeLen(String;)I
@Nullable;() // invisible, parameter 0
IFNULL L1
INVOKEVIRTUAL java/lang/String.length ()I
GOTO L2
ICONST_0
L2
IRETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
No-Nulls
public final static len(String;)I
@NotNull;() // invisible, parameter 0
LDC "str"
INVOKESTATIC Intrinsics.checkParameterIsNotNull (Object;String;)V
INVOKEVIRTUAL String.length ()I
IRETURN
public final static maybeLen(String;)I
@Nullable;() // invisible, parameter 0
IFNULL L1
INVOKEVIRTUAL java/lang/String.length ()I
GOTO L2
ICONST_0
L2
IRETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Extension Functions
fun Context.color(@ColorRes color: Int) =
ContextCompat.getColor(this, color)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Extension Functions
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
youtube.com/c/anzcoders
Extension Functions
fun Context.color(@ColorRes color: Int) =
ContextCompat.getColor(this, color)
// sort of becomes
fun color($receiver: Context, @ColorRes color: Int) =
ContextCompat.getColor($receiver, color)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Inline fun
inline fun inlineFun(f: () -> Unit) {
does()
f()
dat()
}
inlineFun { dis() }
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Inline fun
public final inlineFun(Function0;)V
@NotNull;() // invisible, parameter 0
INVOKEVIRTUAL InlineFuns.does ()V
ALOAD 1
INVOKEINTERFACE Function0.invoke ()
INVOKEVIRTUAL InlineFuns.dat ()V
RETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Inline fun
inlineFun { dis() }
INVOKEVIRTUAL InlineFuns.does ()V
INVOKEVIRTUAL InlineFuns.dis ()V
INVOKEVIRTUAL InlineFuns.dat ()V
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Inline fun
inlineFun { dis() }
INVOKEVIRTUAL InlineFuns.does ()V
INVOKEVIRTUAL InlineFuns.dis ()V
INVOKEVIRTUAL InlineFuns.dat ()V
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Collection Map, Filter &
Sum
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Collection Map, Filter & Sum
class TopicFragment {
fun twoX(x: Int) = x * 2
val numbers = arrayOf(0, 1, 2, 3, 4, 5)
numbers.map(::twoX)
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
BIPUSH 10
ANEWARRAY Integer
INVOKESTATIC Integer.valueOf (I)Integer;
…
INVOKESTATIC Integer.valueOf (I)Integer;
CHECKCAST [LObject;
NEW ArrayList
ARRAYLENGTH
INVOKESPECIAL ArrayList.<init> (I)V
CHECKCAST Collection
ARRAYLENGTH
IF_ICMPGE L9
CHECKCAST Number
INVOKEVIRTUAL Number.intValue ()I
CHECKCAST TopicFragment
INVOKESPECIAL TopicFragment.twoX (I)I
INVOKESTATIC Integer.valueOf (I)Integer;
INVOKEINTERFACE Collection.add (LObject;)GOTO L8
CHECKCAST List
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5};
Object[] $receiver$iv = (Object[])numbers;
TopicFragment var3 = this;
Object[] $receiver$iv$iv = $receiver$iv;
Collection destination$iv$iv = (Collection)(
new ArrayList($receiver$iv.length)
);
for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) {
Object item$iv$iv = $receiver$iv$iv[var6];
int p1 = ((Number)item$iv$iv).intValue();
Integer var13 = ((TopicFragment)var3).twoX(p1);
destination$iv$iv.add(var13);
}
List var10000 = (List)destination$iv$iv;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5};
Object[] $receiver$iv = (Object[])numbers;
TopicFragment var3 = this;
Object[] $receiver$iv$iv = $receiver$iv;
Collection destination$iv$iv = (Collection)(
new ArrayList($receiver$iv.length)
);
for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) {
Object item$iv$iv = $receiver$iv$iv[var6];
int p1 = ((Number)item$iv$iv).intValue();
Integer var13 = ((TopicFragment)var3).twoX(p1);
destination$iv$iv.add(var13);
}
List var10000 = (List)destination$iv$iv;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5};
Object[] $receiver$iv = (Object[])numbers;
TopicFragment var3 = this;
Object[] $receiver$iv$iv = $receiver$iv;
Collection destination$iv$iv = (Collection)(
new ArrayList($receiver$iv.length)
);
for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) {
Object item$iv$iv = $receiver$iv$iv[var6];
int p1 = ((Number)item$iv$iv).intValue();
Integer var13 = ((TopicFragment)var3).twoX(p1);
destination$iv$iv.add(var13);
}
List var10000 = (List)destination$iv$iv;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
val numbers = intArrayOf(0, 1, 2, 3, 4, 5)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
int[] numbers = new int[]{0, 1, 2, 3, 4, 5};
TopicFragment var3 = this;
int[] $receiver$iv$iv = numbers;
Collection destination$iv$iv = (Collection)(
new ArrayList(numbers.length));
for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) {
int item$iv$iv = $receiver$iv$iv[var6];
Integer var13 = ((TopicFragment)var3).twoX(item$iv$iv);
destination$iv$iv.add(var13);
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
intArrayOf(0, 1, 2, 3, 4, 5)
.filter(::isEven)
.map(::twoX)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
int[] $receiver$iv = new int[]{0, 1, 2, 3, 4, 5};
// filter(::isEven)
for(int var5 = 0; var5 < $receiver$iv$iv.length; ++var5) {
int element$iv$iv = $receiver$iv$iv[var5];
if (((TopicFragment)var2).isEven(element$iv$iv)) {
destination$iv$iv.add(element$iv$iv);
}
}
// map(::twoX)
while(var14.hasNext()) {
Object item$iv$iv = var14.next();
int p1 = ((Number)item$iv$iv).intValue();
Integer var12 = ((TopicFragment)var2).twoX(p1);
destination$iv$iv.add(var12);
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
intArrayOf(0, 1, 2, 3, 4, 5)
.asSequence()
.filter(::isEven)
.map(::twoX)
.toList()
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
final class TopicFragment$1
extends FunctionReference implements Function1 {
public synthetic bridge invoke(Object;)
public final invoke(I)Z
public final getOwner()KDeclarationContainer;
public final getName()String;
public final getSignature()String;
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
intArrayOf(0, 1, 2, 3, 4, 5)
.asSequence()
.filter { it % 2 == 0 }
.map { it * 2}
.toList()
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
INVOKESTATIC ArraysKt.asSequence ([I)LSequence;
GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1;
INVOKESTATIC SequencesKt.filter (LSequence;Function1;)
GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2;
INVOKESTATIC SequencesKt.map (LSequence;Function1;)
INVOKESTATIC SequencesKt.toList (LSequence;)List;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
INVOKESTATIC ArraysKt.asSequence ([I)LSequence;
GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1;
INVOKESTATIC SequencesKt.filter (LSequence;Function1;)
GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2;
INVOKESTATIC SequencesKt.map (LSequence;Function1;)
INVOKESTATIC SequencesKt.toList (LSequence;)List;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
INVOKESTATIC ArraysKt.asSequence ([I)LSequence;
GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1;
INVOKESTATIC SequencesKt.filter (LSequence;Function1;)
GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2;
INVOKESTATIC SequencesKt.map (LSequence;Function1;)
INVOKESTATIC SequencesKt.toList (LSequence;)List;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
INVOKESTATIC ArraysKt.asSequence ([I)LSequence;
GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1;
INVOKESTATIC SequencesKt.filter (LSequence;Function1;)
GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2;
INVOKESTATIC SequencesKt.map (LSequence;Function1;)
INVOKESTATIC SequencesKt.toList (LSequence;)List;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Data Classes
data class Speaker(
val description: String,
val talks: List<Talk>,
val profile: String
)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
De-structure data class
val speaker = Speaker(
talks = arrayListOf(),
description = "Bytecode",
profile = ""
)
val (description, talks) = speaker
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final component1()String;
@NotNull;() // invisible
ALOAD 0
GETFIELD Speaker.description : String;
ARETURN
// signature ()LList<LTalk;>;
// declaration: java.util.List<Talk> component2()
public final component2()LList;
@NotNull;() // invisible
ALOAD 0
GETFIELD Speaker.talks : LList;
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
// signature …
// declaration: Speaker copy(java.lang.String, java.util.List<? extends Talk>)
public final copy(String;LList;)LSpeaker;
@NotNull;() // invisible
@NotNull;() // invisible, parameter 0
@NotNull;() // invisible, parameter 1
INVOKESTATIC checkParameterIsNotNull (Object;String;)V
INVOKESTATIC checkParameterIsNotNull (Object;String;)V
NEW Speaker
INVOKESPECIAL Speaker.<init> (String;LList;)V
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
val speaker2 = speaker.copy(
description = "Second speaker"
)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public static synthetic bridge copy$default(LSpeaker;String;LList;IObject;)LSpeaker;
@NotNull;() // invisible
ILOAD 3
ICONST_1
IAND
IFEQ L0
ALOAD 0
GETFIELD Speaker.description : String;
ASTORE 1
L0
ILOAD 3
ICONST_2
IAND
IFEQ L1
ALOAD 0
GETFIELD Speaker.talks : LList;
ASTORE 2
L1
ALOAD 0
ALOAD 1
ALOAD 2
INVOKEVIRTUAL Speaker.copy (String;LList;)LSpeaker;
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public static Speaker copy$default(
Speaker var0,
String var1, List var2, String var3,
int var4, Object var5
) {
if ((var4 & 1) != 0) {
var1 = var0.description;
}
if ((var4 & 2) != 0) {
var2 = var0.talks;
}
if ((var4 & 4) != 0) {
var3 = var0.profile;
}
return var0.copy(var1, var2, var3);
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Lambdas
— SAM (Single Access Method)
— Non-Capturing Lambdas
— Capturing Lambdas
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
SAMs
view.setOnClickListener {
print("Hello")
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
SAMs
final class Sam$1 implements View$OnClickListener {
public final onClick(Landroid/view/View;)V
LDC "Hello"
INVOKEVIRTUAL PrintStream.print (Object;)V
RETURN
<init>()V
INVOKESPECIAL Object.<init> ()V
RETURN
public final static Sam$1; INSTANCE
static <clinit>()V
NEW Sam$1
DUP
INVOKESPECIAL Sam$1.<init> ()V
PUTSTATIC Sam$1.INSTANCE : Sam$1;
RETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class Lmd {
private val lambda = {
"I'm a lambda"
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class Lmd {
// signature Function0<String;>;
// declaration: Function0<java.lang.String>
private final Function0; lambda
public <init>()V
// …
ALOAD 0
GETSTATIC Lmd$lambda$1.INSTANCE : Lmd$lambda$1;
CHECKCAST Function0
PUTFIELD Lmd.lambda : Function0;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
final class Lmd$lambda$1
extends Lambda
implements Function0 {
<init>()V
INVOKESPECIAL Lambda.<init> (I)V
RETURN
public final static Lmd$lambda$1; INSTANCE
static <clinit>()V
NEW Lmd$lambda$1
DUP
INVOKESPECIAL Lmd$lambda$1.<init> ()V
PUTSTATIC Lmd$lambda$1.INSTANCE : Lmd$lambda$1;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public synthetic bridge invoke()Object;
L0
LINENUMBER 3 L0
ALOAD 0
INVOKEVIRTUAL Lmd$lambda$1.invoke ()String;
ARETURN
// access flags 0x11
public final invoke()String;
@NotNull;() // invisible
L0
LINENUMBER 5 L0
LDC "I'm a lambda"
L1
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class Lmd {
private val lambda = {
"I'm a lambda"
}
val value = lambda()
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class Lmd {
public <init>()V
…
ALOAD 0
GETFIELD Lmd.lambda : Function0;
INVOKEINTERFACE Function0.invoke ()Object;
CHECKCAST String
}
final class public Lmd$lambda$1 {
public synthetic bridge invoke()Object;
Lmd$lambda$1.invoke ()String;
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Lambda s and Field
class Lmd (
private val speaker: Speaker
) {
private val lambda = {
speaker.name
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
final class Lmd$lambda$1 {
final synthetic Lmd; this$0
public final invoke()String;
@NotNull;() // invisible
GETFIELD Lmd$lambda$1.this$0 : Lmd;
INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker;
INVOKEVIRTUAL Speaker.getName ()String;
ARETURN
<init>(Lmd;)V
PUTFIELD Lmd$lambda$1.this$0 : Lmd;
INVOKESPECIAL Lambda.<init> (I)V
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
final class Lmd$lambda$1 {
final synthetic Lmd; this$0
public final invoke()String;
@NotNull;() // invisible
GETFIELD Lmd$lambda$1.this$0 : Lmd;
INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker;
INVOKEVIRTUAL Speaker.getName ()String;
ARETURN
<init>(Lmd;)V
PUTFIELD Lmd$lambda$1.this$0 : Lmd;
INVOKESPECIAL Lambda.<init> (I)V
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class Lmd {
public final static synthetic access$getSpeaker$p(Lmd;)Speaker;
@NotNull;() // invisible
ALOAD 0
GETFIELD Lmd.speaker : Speaker;
ARETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class Lmd (
@JvmField protected
private val speaker: Speaker
){
private val lambda = {
speaker.name
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class Lmd (
@Suppress("WARNINGS")
@JvmField
protected
private val speaker: Speaker = Speaker("speaker")
){
private val lambda = {
speaker.name
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
final class Lmd$lambda$1 {
public final invoke()String;
GETFIELD Lmd$lambda$1.this$0 : LLmd;
GETFIELD Lmd.speaker : LSpeaker;
INVOKEVIRTUAL Speaker.getName ()String;
ARETURNdas.lambda : Function0;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
File values and
functions
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
// file name Objects
private val speaker = Speaker()
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
youtube.com/c/anzcoders
// file name Objects
private val speaker = Speaker()
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
youtube.com/c/anzcoders
fun someStr() = "Some String"
// Becomes
public final class ObjectsKt {
public final static someStr() String;
@NotNull;() // invisible
LDC "Some String"
ARETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
private val someStr = "Some String"
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
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
youtube.com/c/anzcoders
private const val someStr = "Some String"
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class ObjectsKt {
private final static String; someStr = "Some String"
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Objects
object AnObject
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class AnObject {
public final static AnObject; INSTANCE
private <init>()V
INVOKESPECIAL Object.<init> ()V
RETURN
static <clinit>()V
NEW AnObject
DUP
INVOKESPECIAL AnObject.<init> ()V
PUTSTATIC AnObject.INSTANCE : AnObject;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
object AnObject {
val name = "Mitchell"
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class AnObject {
private final static String; name = "Mitchell"
@NotNull;() // invisible
public final getName()String;
@NotNull;() // invisible
GETSTATIC AnObject.name : String;
ARETURN
static <clinit>()V
LDC "Mitchell"
PUTSTATIC AnObject.name : String;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
object AnObject {
const val name = "Mitchell"
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class AnObject {
public final static String; name = "Mitchell"
public final static LAnObject; INSTANCE
private <init>()V
INVOKESPECIAL Object.<init> ()V
RETURN
static <clinit>()V
NEW AnObject
DUP
INVOKESPECIAL AnObject.<init> ()V
PUTSTATIC AnObject.INSTANCE : LAnObject;
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
object AnObject {
fun speaker() = Speaker()
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class AnObject {
public final speaker() Speaker;
@NotNull;() // invisible
NEW Speaker
DUP
INVOKESPECIAL Speaker.<init> ()V
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
object AnObject {
@JvmStatic
fun speaker() = Speaker()
}
// With @JvmStatic
public final class AnObject {
public final static speaker() Speaker;
@JvmStatic;()
@NotNull;() // invisible
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Companion Object
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicFragment {
companion object {
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment {
public <init>()V
static <clinit>()V
NEW TopicFragment$Companion
DUP
ACONST_NULL
INVOKESPECIAL TopicFragment$Companion.<init> (
DefaultConstructorMarker;
)V
PUTSTATIC TopicFragment.Companion : TopicFragment$Companion;
RETURN
public final static TopicFragment$Companion; Companion
public final static INNERCLASS
TopicFragment$Companion TopicFragment Companion
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment$Companion {
private <init>()V
INVOKESPECIAL Object.<init> ()V
RETURN
public synthetic <init>(DefaultConstructorMarker;)V
INVOKESPECIAL TopicFragment$Companion.<init> ()V
RETURN
public final static INNERCLASS
TopicFragment$Companion TopicFragment Companion
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicFragment {
companion object {
val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID"
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicFragment {
init {
EXTRA_TOPIC_ID
}
companion object {
val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID"
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment {
private final static String; EXTRA_TOPIC_ID =
"EXTRA_TOPIC_ID"
static <clinit>()V
NEW TopicFragment$Companion
…
LDC "EXTRA_TOPIC_ID"
PUTSTATIC TopicFragment
.EXTRA_TOPIC_ID : String;
RETURN
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment {
public <init>()V
GETSTATIC Companion : $Companion;
INVOKEVIRTUAL $Companion
.getEXTRA_TOPIC_ID ()String;
POP
…
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment$Companion {
public final getEXTRA_TOPIC_ID()String;
@NotNull;() // invisible
L0
LINENUMBER 11 L0
INVOKESTATIC TopicFragment.access$getEXTRA_TOPIC_ID$cp ()String;
ARETURN
}
public final class TopicFragment {
public final static synthetic access$getEXTRA_TOPIC_ID$cp()String;
@NotNull;() // invisible
GETSTATIC TopicFragment.EXTRA_TOPIC_ID : String;
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicFragment {
init {
EXTRA_TOPIC_ID
}
companion object {
const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID"
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicFragment {
public <init>()V
INVOKESPECIAL Object.<init> ()V
// Now all we get is metadata
LINENUMBER 6 L1
RETURN
public final static String; EXTRA_TOPIC_ID =
"EXTRA_TOPIC_ID"
@NotNull;() // invisible
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
package io.github.droidkaigi.confsched2018.data.api.response.mapper
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
youtube.com/c/anzcoders
private object FormatCompanion {
@JvmField
val FORMATTER: DateTimeFormatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
}
class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() {
…
companion object {
fun parseDateString(dateString: String?): LocalDateTime =
LocalDateTime.parse(dateString, FORMATTER)
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
/* package private */ final class FormatCompanion {
public final static DateTimeFormatter; FORMATTER
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicFragment {
companion object {
private const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID"
fun newInstance(topicId: Int) {
}
}
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Reducing Synthetic Methods
class TopicDetailViewModel
@Inject constructor(
private val repository: SessionRepository,
private val schedulerProvider: SchedulerProvider
) : ViewModel(), LifecycleObserver {
var topicId: Int = 0
val topicSessions: LiveDataSessions by lazy {
repository.topicSessions
.map {
it
.filter { it.key.id == topicId }
.map { it.key to it.value }
.first()
}
.toResult(schedulerProvider)
.toLiveData()
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
public final class TopicDetailViewModel
extends android/arch/lifecycle/ViewModel
implements android/arch/lifecycle/LifecycleObserver {
public final static synthetic access$getRepository
$p(LTopicDetailViewModel;)SessionRepository;
@NotNull;() // invisible
L0
LINENUMBER 20 L0
ALOAD 0
GETFIELD TopicDetailViewModel.repository : SessionRepository;
ARETURN
public final static synthetic access$getSchedulerProvider
$p(LTopicDetailViewModel;)SchedulerProvider;
@NotNull;() // invisible
L0
LINENUMBER 20 L0
ALOAD 0
GETFIELD TopicDetailViewModel.schedulerProvider : SchedulerProvider;
ARETURN
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicDetailViewModel
@Inject constructor(
private val repository: SessionRepository,
private val schedulerProvider: SchedulerProvider
) : ViewModel(), LifecycleObserver {
var topicId: Int = 0
val topicSessions: LiveDataSessions by lazy {
repository.topicSessions
.map {
it
.filter { it.key.id == topicId }
.map { it.key to it.value }
.first()
}
.toResult(schedulerProvider)
.toLiveData()
}
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
class TopicDetailViewModel
@Inject constructor(
@JvmField protected
val repository: SessionRepository,
@JvmField protected
val schedulerProvider: SchedulerProvider
)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
// protected is effectively private in final classes
class TopicDetailViewModel
@Inject
@Suppress("warnings")
constructor(
@JvmField protected
val repository: SessionRepository,
@JvmField protected
val schedulerProvider: SchedulerProvider
)
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders
Mitchell Tilbrook
@sir_tilbrook
Sydney Tech Talks
youtube.com/c/anzcoders
Moneytree
Android Developer
moneytree.jp
Mitchell Tilbook @sir_tilbrook
youtube.com/c/anzcoders

More Related Content

What's hot

Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!John De Goes
 
CBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical fileCBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical filePranav Ghildiyal
 
Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python TricksBryan Helmig
 
20180310 functional programming
20180310 functional programming20180310 functional programming
20180310 functional programmingChiwon Song
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳Yuri Inoue
 
Quarto Presentations with Reveal.js
Quarto Presentations with Reveal.jsQuarto Presentations with Reveal.js
Quarto Presentations with Reveal.jsJJAllaire1
 
20191116 custom operators in swift
20191116 custom operators in swift20191116 custom operators in swift
20191116 custom operators in swiftChiwon Song
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!Boy Baukema
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python Chetan Giridhar
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to PerlSway Wang
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit partsMaxim Zaks
 
Exploring slides
Exploring slidesExploring slides
Exploring slidesakaptur
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6FITC
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 
Ruby on rails tips
Ruby  on rails tipsRuby  on rails tips
Ruby on rails tipsBinBin He
 

What's hot (20)

Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
CBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical fileCBSE Class XII Comp sc practical file
CBSE Class XII Comp sc practical file
 
Why Kotlin is your next language?
Why Kotlin is your next language? Why Kotlin is your next language?
Why Kotlin is your next language?
 
Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python Tricks
 
20180310 functional programming
20180310 functional programming20180310 functional programming
20180310 functional programming
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳
 
Quarto Presentations with Reveal.js
Quarto Presentations with Reveal.jsQuarto Presentations with Reveal.js
Quarto Presentations with Reveal.js
 
20191116 custom operators in swift
20191116 custom operators in swift20191116 custom operators in swift
20191116 custom operators in swift
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
 
Galios: Python Programming
Galios: Python Programming Galios: Python Programming
Galios: Python Programming
 
Stackful
StackfulStackful
Stackful
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
 
Exploring slides
Exploring slidesExploring slides
Exploring slides
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 
C++totural file
C++totural fileC++totural file
C++totural file
 
Ruby on rails tips
Ruby  on rails tipsRuby  on rails tips
Ruby on rails tips
 

Similar to Kotlin Backstage

Kotlin Backstage - Android Makers Paris 2018
Kotlin Backstage - Android Makers Paris 2018Kotlin Backstage - Android Makers Paris 2018
Kotlin Backstage - Android Makers Paris 2018Mitchell Tilbrook
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Waytdc-globalcode
 
Functions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingFunctions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingPaul Solt
 
Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android DevelopersHassan Abid
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and InferenceRichard Fox
 
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)AvitoTech
 
Get Functional on the CLR: Intro to Functional Programming with F#
Get Functional on the CLR: Intro to Functional Programming with F# Get Functional on the CLR: Intro to Functional Programming with F#
Get Functional on the CLR: Intro to Functional Programming with F# David Alpert
 
Effective C#
Effective C#Effective C#
Effective C#lantoli
 
Connect() Mini 2016
Connect() Mini 2016Connect() Mini 2016
Connect() Mini 2016Jeff Chu
 
The What, Why And How of ClojureScript
The What, Why And How of ClojureScriptThe What, Why And How of ClojureScript
The What, Why And How of ClojureScriptIvan Bokii
 
つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~kamedon39
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchainedEduard Tomàs
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFabio Collini
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptxAzharFauzan9
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptxIvanZawPhyo
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in HaskellHiromi Ishii
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Andrey Akinshin
 

Similar to Kotlin Backstage (20)

Kotlin Backstage - Android Makers Paris 2018
Kotlin Backstage - Android Makers Paris 2018Kotlin Backstage - Android Makers Paris 2018
Kotlin Backstage - Android Makers Paris 2018
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
 
Functions in Objective-C and C Programming
Functions in Objective-C and C ProgrammingFunctions in Objective-C and C Programming
Functions in Objective-C and C Programming
 
Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android Developers
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
 
Get Functional on the CLR: Intro to Functional Programming with F#
Get Functional on the CLR: Intro to Functional Programming with F# Get Functional on the CLR: Intro to Functional Programming with F#
Get Functional on the CLR: Intro to Functional Programming with F#
 
Effective C#
Effective C#Effective C#
Effective C#
 
Connect() Mini 2016
Connect() Mini 2016Connect() Mini 2016
Connect() Mini 2016
 
The What, Why And How of ClojureScript
The What, Why And How of ClojureScriptThe What, Why And How of ClojureScript
The What, Why And How of ClojureScript
 
つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
 
Arrays
ArraysArrays
Arrays
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in Haskell
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 

Recently uploaded

Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 

Recently uploaded (20)

Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 

Kotlin Backstage

  • 1. Kotlin Backstage Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 2. Kotlin Backstage — What Kotlin generates in bytecode — Impact of const — Objects & Statics — Impact of Scoping on method count Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 3. Primitives val number: Int = 10 val number: Int? = 10 Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 4. Primitives private final static I number = 10 private final static L…/Integer; nullableNumber @L…/Nullable;() // invisible Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 5. String Interpolation val i = 10 val s = "i = $i" // evaluates to "i = 10" Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 6. String Interpolation NEW StringBuilder DUP INVOKESPECIAL StringBuilder.<init> ()V LDC "i = " INVOKEVIRTUAL StringBuilder.append (LString;)LStringBuilder; GETSTATIC ExtKt.i : I INVOKEVIRTUAL StringBuilder.append (I)LStringBuilder; INVOKEVIRTUAL StringBuilder.toString ()LString; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 7. Classes class Speaker(val talk: String) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 8. 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 youtube.com/c/anzcoders
  • 9. Classes class Speaker(@JvmField val talk: String) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 10. Classes public final class Speaker { public final String; talk @JvmField;() // invisible @NotNull;() // invisible public <init>(String;)V { … } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 11. Nulls fun len(str: String) = str.length fun maybeLen(str: String?) = str?.length ?: 0 Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 12. No-Nulls public final static len(String;)I @NotNull;() // invisible, parameter 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull (Object;String;)V INVOKEVIRTUAL String.length ()I IRETURN public final static maybeLen(String;)I @Nullable;() // invisible, parameter 0 IFNULL L1 INVOKEVIRTUAL java/lang/String.length ()I GOTO L2 ICONST_0 L2 IRETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 13. No-Nulls public final static len(String;)I @NotNull;() // invisible, parameter 0 LDC "str" INVOKESTATIC Intrinsics.checkParameterIsNotNull (Object;String;)V INVOKEVIRTUAL String.length ()I IRETURN public final static maybeLen(String;)I @Nullable;() // invisible, parameter 0 IFNULL L1 INVOKEVIRTUAL java/lang/String.length ()I GOTO L2 ICONST_0 L2 IRETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 14. Extension Functions fun Context.color(@ColorRes color: Int) = ContextCompat.getColor(this, color) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 15. Extension Functions 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 youtube.com/c/anzcoders
  • 16. Extension Functions fun Context.color(@ColorRes color: Int) = ContextCompat.getColor(this, color) // sort of becomes fun color($receiver: Context, @ColorRes color: Int) = ContextCompat.getColor($receiver, color) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 17. Inline fun inline fun inlineFun(f: () -> Unit) { does() f() dat() } inlineFun { dis() } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 18. Inline fun public final inlineFun(Function0;)V @NotNull;() // invisible, parameter 0 INVOKEVIRTUAL InlineFuns.does ()V ALOAD 1 INVOKEINTERFACE Function0.invoke () INVOKEVIRTUAL InlineFuns.dat ()V RETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 19. Inline fun inlineFun { dis() } INVOKEVIRTUAL InlineFuns.does ()V INVOKEVIRTUAL InlineFuns.dis ()V INVOKEVIRTUAL InlineFuns.dat ()V Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 20. Inline fun inlineFun { dis() } INVOKEVIRTUAL InlineFuns.does ()V INVOKEVIRTUAL InlineFuns.dis ()V INVOKEVIRTUAL InlineFuns.dat ()V Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 21. Collection Map, Filter & Sum Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 22. Collection Map, Filter & Sum class TopicFragment { fun twoX(x: Int) = x * 2 val numbers = arrayOf(0, 1, 2, 3, 4, 5) numbers.map(::twoX) } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 23. BIPUSH 10 ANEWARRAY Integer INVOKESTATIC Integer.valueOf (I)Integer; … INVOKESTATIC Integer.valueOf (I)Integer; CHECKCAST [LObject; NEW ArrayList ARRAYLENGTH INVOKESPECIAL ArrayList.<init> (I)V CHECKCAST Collection ARRAYLENGTH IF_ICMPGE L9 CHECKCAST Number INVOKEVIRTUAL Number.intValue ()I CHECKCAST TopicFragment INVOKESPECIAL TopicFragment.twoX (I)I INVOKESTATIC Integer.valueOf (I)Integer; INVOKEINTERFACE Collection.add (LObject;)GOTO L8 CHECKCAST List Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 24. Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5}; Object[] $receiver$iv = (Object[])numbers; TopicFragment var3 = this; Object[] $receiver$iv$iv = $receiver$iv; Collection destination$iv$iv = (Collection)( new ArrayList($receiver$iv.length) ); for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) { Object item$iv$iv = $receiver$iv$iv[var6]; int p1 = ((Number)item$iv$iv).intValue(); Integer var13 = ((TopicFragment)var3).twoX(p1); destination$iv$iv.add(var13); } List var10000 = (List)destination$iv$iv; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 25. Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5}; Object[] $receiver$iv = (Object[])numbers; TopicFragment var3 = this; Object[] $receiver$iv$iv = $receiver$iv; Collection destination$iv$iv = (Collection)( new ArrayList($receiver$iv.length) ); for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) { Object item$iv$iv = $receiver$iv$iv[var6]; int p1 = ((Number)item$iv$iv).intValue(); Integer var13 = ((TopicFragment)var3).twoX(p1); destination$iv$iv.add(var13); } List var10000 = (List)destination$iv$iv; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 26. Integer[] numbers = new Integer[]{0, 1, 2, 3, 4, 5}; Object[] $receiver$iv = (Object[])numbers; TopicFragment var3 = this; Object[] $receiver$iv$iv = $receiver$iv; Collection destination$iv$iv = (Collection)( new ArrayList($receiver$iv.length) ); for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) { Object item$iv$iv = $receiver$iv$iv[var6]; int p1 = ((Number)item$iv$iv).intValue(); Integer var13 = ((TopicFragment)var3).twoX(p1); destination$iv$iv.add(var13); } List var10000 = (List)destination$iv$iv; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 27. val numbers = intArrayOf(0, 1, 2, 3, 4, 5) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 28. int[] numbers = new int[]{0, 1, 2, 3, 4, 5}; TopicFragment var3 = this; int[] $receiver$iv$iv = numbers; Collection destination$iv$iv = (Collection)( new ArrayList(numbers.length)); for(int var6 = 0; var6 < $receiver$iv$iv.length; ++var6) { int item$iv$iv = $receiver$iv$iv[var6]; Integer var13 = ((TopicFragment)var3).twoX(item$iv$iv); destination$iv$iv.add(var13); } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 29. intArrayOf(0, 1, 2, 3, 4, 5) .filter(::isEven) .map(::twoX) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 30. int[] $receiver$iv = new int[]{0, 1, 2, 3, 4, 5}; // filter(::isEven) for(int var5 = 0; var5 < $receiver$iv$iv.length; ++var5) { int element$iv$iv = $receiver$iv$iv[var5]; if (((TopicFragment)var2).isEven(element$iv$iv)) { destination$iv$iv.add(element$iv$iv); } } // map(::twoX) while(var14.hasNext()) { Object item$iv$iv = var14.next(); int p1 = ((Number)item$iv$iv).intValue(); Integer var12 = ((TopicFragment)var2).twoX(p1); destination$iv$iv.add(var12); } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 31. intArrayOf(0, 1, 2, 3, 4, 5) .asSequence() .filter(::isEven) .map(::twoX) .toList() Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 32. final class TopicFragment$1 extends FunctionReference implements Function1 { public synthetic bridge invoke(Object;) public final invoke(I)Z public final getOwner()KDeclarationContainer; public final getName()String; public final getSignature()String; } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 33. intArrayOf(0, 1, 2, 3, 4, 5) .asSequence() .filter { it % 2 == 0 } .map { it * 2} .toList() Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 34. INVOKESTATIC ArraysKt.asSequence ([I)LSequence; GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1; INVOKESTATIC SequencesKt.filter (LSequence;Function1;) GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2; INVOKESTATIC SequencesKt.map (LSequence;Function1;) INVOKESTATIC SequencesKt.toList (LSequence;)List; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 35. INVOKESTATIC ArraysKt.asSequence ([I)LSequence; GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1; INVOKESTATIC SequencesKt.filter (LSequence;Function1;) GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2; INVOKESTATIC SequencesKt.map (LSequence;Function1;) INVOKESTATIC SequencesKt.toList (LSequence;)List; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 36. INVOKESTATIC ArraysKt.asSequence ([I)LSequence; GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1; INVOKESTATIC SequencesKt.filter (LSequence;Function1;) GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2; INVOKESTATIC SequencesKt.map (LSequence;Function1;) INVOKESTATIC SequencesKt.toList (LSequence;)List; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 37. INVOKESTATIC ArraysKt.asSequence ([I)LSequence; GETSTATIC TopicFragment$1.INSTANCE : TopicFragment$1; INVOKESTATIC SequencesKt.filter (LSequence;Function1;) GETSTATIC TopicFragment$2.INSTANCE : TopicFragment$2; INVOKESTATIC SequencesKt.map (LSequence;Function1;) INVOKESTATIC SequencesKt.toList (LSequence;)List; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 38. Data Classes data class Speaker( val description: String, val talks: List<Talk>, val profile: String ) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 39. De-structure data class val speaker = Speaker( talks = arrayListOf(), description = "Bytecode", profile = "" ) val (description, talks) = speaker Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 40. public final component1()String; @NotNull;() // invisible ALOAD 0 GETFIELD Speaker.description : String; ARETURN // signature ()LList<LTalk;>; // declaration: java.util.List<Talk> component2() public final component2()LList; @NotNull;() // invisible ALOAD 0 GETFIELD Speaker.talks : LList; ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 41. // signature … // declaration: Speaker copy(java.lang.String, java.util.List<? extends Talk>) public final copy(String;LList;)LSpeaker; @NotNull;() // invisible @NotNull;() // invisible, parameter 0 @NotNull;() // invisible, parameter 1 INVOKESTATIC checkParameterIsNotNull (Object;String;)V INVOKESTATIC checkParameterIsNotNull (Object;String;)V NEW Speaker INVOKESPECIAL Speaker.<init> (String;LList;)V ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 42. val speaker2 = speaker.copy( description = "Second speaker" ) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 43. public static synthetic bridge copy$default(LSpeaker;String;LList;IObject;)LSpeaker; @NotNull;() // invisible ILOAD 3 ICONST_1 IAND IFEQ L0 ALOAD 0 GETFIELD Speaker.description : String; ASTORE 1 L0 ILOAD 3 ICONST_2 IAND IFEQ L1 ALOAD 0 GETFIELD Speaker.talks : LList; ASTORE 2 L1 ALOAD 0 ALOAD 1 ALOAD 2 INVOKEVIRTUAL Speaker.copy (String;LList;)LSpeaker; ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 44. public static Speaker copy$default( Speaker var0, String var1, List var2, String var3, int var4, Object var5 ) { if ((var4 & 1) != 0) { var1 = var0.description; } if ((var4 & 2) != 0) { var2 = var0.talks; } if ((var4 & 4) != 0) { var3 = var0.profile; } return var0.copy(var1, var2, var3); } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 45. Lambdas — SAM (Single Access Method) — Non-Capturing Lambdas — Capturing Lambdas Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 47. SAMs final class Sam$1 implements View$OnClickListener { public final onClick(Landroid/view/View;)V LDC "Hello" INVOKEVIRTUAL PrintStream.print (Object;)V RETURN <init>()V INVOKESPECIAL Object.<init> ()V RETURN public final static Sam$1; INSTANCE static <clinit>()V NEW Sam$1 DUP INVOKESPECIAL Sam$1.<init> ()V PUTSTATIC Sam$1.INSTANCE : Sam$1; RETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 48. class Lmd { private val lambda = { "I'm a lambda" } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 49. public final class Lmd { // signature Function0<String;>; // declaration: Function0<java.lang.String> private final Function0; lambda public <init>()V // … ALOAD 0 GETSTATIC Lmd$lambda$1.INSTANCE : Lmd$lambda$1; CHECKCAST Function0 PUTFIELD Lmd.lambda : Function0; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 50. final class Lmd$lambda$1 extends Lambda implements Function0 { <init>()V INVOKESPECIAL Lambda.<init> (I)V RETURN public final static Lmd$lambda$1; INSTANCE static <clinit>()V NEW Lmd$lambda$1 DUP INVOKESPECIAL Lmd$lambda$1.<init> ()V PUTSTATIC Lmd$lambda$1.INSTANCE : Lmd$lambda$1; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 51. public synthetic bridge invoke()Object; L0 LINENUMBER 3 L0 ALOAD 0 INVOKEVIRTUAL Lmd$lambda$1.invoke ()String; ARETURN // access flags 0x11 public final invoke()String; @NotNull;() // invisible L0 LINENUMBER 5 L0 LDC "I'm a lambda" L1 ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 52. class Lmd { private val lambda = { "I'm a lambda" } val value = lambda() } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 53. public final class Lmd { public <init>()V … ALOAD 0 GETFIELD Lmd.lambda : Function0; INVOKEINTERFACE Function0.invoke ()Object; CHECKCAST String } final class public Lmd$lambda$1 { public synthetic bridge invoke()Object; Lmd$lambda$1.invoke ()String; } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 54. Lambda s and Field class Lmd ( private val speaker: Speaker ) { private val lambda = { speaker.name } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 55. final class Lmd$lambda$1 { final synthetic Lmd; this$0 public final invoke()String; @NotNull;() // invisible GETFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker; INVOKEVIRTUAL Speaker.getName ()String; ARETURN <init>(Lmd;)V PUTFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESPECIAL Lambda.<init> (I)V RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 56. final class Lmd$lambda$1 { final synthetic Lmd; this$0 public final invoke()String; @NotNull;() // invisible GETFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESTATIC Lmd.access$getSpeaker$p (Lmd;)LSpeaker; INVOKEVIRTUAL Speaker.getName ()String; ARETURN <init>(Lmd;)V PUTFIELD Lmd$lambda$1.this$0 : Lmd; INVOKESPECIAL Lambda.<init> (I)V RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 57. public final class Lmd { public final static synthetic access$getSpeaker$p(Lmd;)Speaker; @NotNull;() // invisible ALOAD 0 GETFIELD Lmd.speaker : Speaker; ARETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 58. class Lmd ( @JvmField protected private val speaker: Speaker ){ private val lambda = { speaker.name } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 59. class Lmd ( @Suppress("WARNINGS") @JvmField protected private val speaker: Speaker = Speaker("speaker") ){ private val lambda = { speaker.name } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 60. final class Lmd$lambda$1 { public final invoke()String; GETFIELD Lmd$lambda$1.this$0 : LLmd; GETFIELD Lmd.speaker : LSpeaker; INVOKEVIRTUAL Speaker.getName ()String; ARETURNdas.lambda : Function0; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 61. File values and functions Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 62. // file name Objects private val speaker = Speaker() 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 youtube.com/c/anzcoders
  • 63. // file name Objects private val speaker = Speaker() 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 youtube.com/c/anzcoders
  • 64. fun someStr() = "Some String" // Becomes public final class ObjectsKt { public final static someStr() String; @NotNull;() // invisible LDC "Some String" ARETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 65. private val someStr = "Some String" Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 66. 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 youtube.com/c/anzcoders
  • 67. private const val someStr = "Some String" Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 68. public final class ObjectsKt { private final static String; someStr = "Some String" } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 69. Objects object AnObject Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 70. public final class AnObject { public final static AnObject; INSTANCE private <init>()V INVOKESPECIAL Object.<init> ()V RETURN static <clinit>()V NEW AnObject DUP INVOKESPECIAL AnObject.<init> ()V PUTSTATIC AnObject.INSTANCE : AnObject; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 71. object AnObject { val name = "Mitchell" } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 72. public final class AnObject { private final static String; name = "Mitchell" @NotNull;() // invisible public final getName()String; @NotNull;() // invisible GETSTATIC AnObject.name : String; ARETURN static <clinit>()V LDC "Mitchell" PUTSTATIC AnObject.name : String; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 73. object AnObject { const val name = "Mitchell" } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 74. public final class AnObject { public final static String; name = "Mitchell" public final static LAnObject; INSTANCE private <init>()V INVOKESPECIAL Object.<init> ()V RETURN static <clinit>()V NEW AnObject DUP INVOKESPECIAL AnObject.<init> ()V PUTSTATIC AnObject.INSTANCE : LAnObject; Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 75. object AnObject { fun speaker() = Speaker() } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 76. public final class AnObject { public final speaker() Speaker; @NotNull;() // invisible NEW Speaker DUP INVOKESPECIAL Speaker.<init> ()V ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 77. object AnObject { @JvmStatic fun speaker() = Speaker() } // With @JvmStatic public final class AnObject { public final static speaker() Speaker; @JvmStatic;() @NotNull;() // invisible } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 78. Companion Object Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 79. class TopicFragment { companion object { } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 80. public final class TopicFragment { public <init>()V static <clinit>()V NEW TopicFragment$Companion DUP ACONST_NULL INVOKESPECIAL TopicFragment$Companion.<init> ( DefaultConstructorMarker; )V PUTSTATIC TopicFragment.Companion : TopicFragment$Companion; RETURN public final static TopicFragment$Companion; Companion public final static INNERCLASS TopicFragment$Companion TopicFragment Companion } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 81. public final class TopicFragment$Companion { private <init>()V INVOKESPECIAL Object.<init> ()V RETURN public synthetic <init>(DefaultConstructorMarker;)V INVOKESPECIAL TopicFragment$Companion.<init> ()V RETURN public final static INNERCLASS TopicFragment$Companion TopicFragment Companion } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 82. class TopicFragment { companion object { val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 83. class TopicFragment { init { EXTRA_TOPIC_ID } companion object { val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 84. public final class TopicFragment { private final static String; EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" static <clinit>()V NEW TopicFragment$Companion … LDC "EXTRA_TOPIC_ID" PUTSTATIC TopicFragment .EXTRA_TOPIC_ID : String; RETURN } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 85. public final class TopicFragment { public <init>()V GETSTATIC Companion : $Companion; INVOKEVIRTUAL $Companion .getEXTRA_TOPIC_ID ()String; POP … } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 86. public final class TopicFragment$Companion { public final getEXTRA_TOPIC_ID()String; @NotNull;() // invisible L0 LINENUMBER 11 L0 INVOKESTATIC TopicFragment.access$getEXTRA_TOPIC_ID$cp ()String; ARETURN } public final class TopicFragment { public final static synthetic access$getEXTRA_TOPIC_ID$cp()String; @NotNull;() // invisible GETSTATIC TopicFragment.EXTRA_TOPIC_ID : String; ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 88. class TopicFragment { init { EXTRA_TOPIC_ID } companion object { const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 89. public final class TopicFragment { public <init>()V INVOKESPECIAL Object.<init> ()V // Now all we get is metadata LINENUMBER 6 L1 RETURN public final static String; EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" @NotNull;() // invisible Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 90. package io.github.droidkaigi.confsched2018.data.api.response.mapper 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 youtube.com/c/anzcoders
  • 91. private object FormatCompanion { @JvmField val FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss") } class LocalDateTimeAdapter : JsonAdapter<LocalDateTime>() { … companion object { fun parseDateString(dateString: String?): LocalDateTime = LocalDateTime.parse(dateString, FORMATTER) } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 92. /* package private */ final class FormatCompanion { public final static DateTimeFormatter; FORMATTER } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 93. class TopicFragment { companion object { private const val EXTRA_TOPIC_ID = "EXTRA_TOPIC_ID" fun newInstance(topicId: Int) { } } } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 94. Reducing Synthetic Methods class TopicDetailViewModel @Inject constructor( private val repository: SessionRepository, private val schedulerProvider: SchedulerProvider ) : ViewModel(), LifecycleObserver { var topicId: Int = 0 val topicSessions: LiveDataSessions by lazy { repository.topicSessions .map { it .filter { it.key.id == topicId } .map { it.key to it.value } .first() } .toResult(schedulerProvider) .toLiveData() } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 95. public final class TopicDetailViewModel extends android/arch/lifecycle/ViewModel implements android/arch/lifecycle/LifecycleObserver { public final static synthetic access$getRepository $p(LTopicDetailViewModel;)SessionRepository; @NotNull;() // invisible L0 LINENUMBER 20 L0 ALOAD 0 GETFIELD TopicDetailViewModel.repository : SessionRepository; ARETURN public final static synthetic access$getSchedulerProvider $p(LTopicDetailViewModel;)SchedulerProvider; @NotNull;() // invisible L0 LINENUMBER 20 L0 ALOAD 0 GETFIELD TopicDetailViewModel.schedulerProvider : SchedulerProvider; ARETURN Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 96. class TopicDetailViewModel @Inject constructor( private val repository: SessionRepository, private val schedulerProvider: SchedulerProvider ) : ViewModel(), LifecycleObserver { var topicId: Int = 0 val topicSessions: LiveDataSessions by lazy { repository.topicSessions .map { it .filter { it.key.id == topicId } .map { it.key to it.value } .first() } .toResult(schedulerProvider) .toLiveData() } Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 97. class TopicDetailViewModel @Inject constructor( @JvmField protected val repository: SessionRepository, @JvmField protected val schedulerProvider: SchedulerProvider ) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 98. // protected is effectively private in final classes class TopicDetailViewModel @Inject @Suppress("warnings") constructor( @JvmField protected val repository: SessionRepository, @JvmField protected val schedulerProvider: SchedulerProvider ) Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders
  • 99. Mitchell Tilbrook @sir_tilbrook Sydney Tech Talks youtube.com/c/anzcoders Moneytree Android Developer moneytree.jp Mitchell Tilbook @sir_tilbrook youtube.com/c/anzcoders