SlideShare a Scribd company logo
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 file
Pranav Ghildiyal
 
Why Kotlin is your next language?
Why Kotlin is your next language? Why Kotlin is your next language?
Why Kotlin is your next language?
Aliaksei Zhynhiarouski
 
Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python Tricks
Bryan Helmig
 
20180310 functional programming
20180310 functional programming20180310 functional programming
20180310 functional programming
Chiwon 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.js
JJAllaire1
 
20191116 custom operators in swift
20191116 custom operators in swift20191116 custom operators in swift
20191116 custom operators in swift
Chiwon Song
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
Boy Baukema
 
Galios: Python Programming
Galios: Python Programming Galios: Python Programming
Galios: Python Programming
Kishoj Bajracharya
 
Stackful
StackfulStackful
Stackful
Erik Rose
 
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 Perl
Sway Wang
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
Han Lee
 
C++ tutorial
C++ tutorialC++ tutorial
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
Maxim Zaks
 
Exploring slides
Exploring slidesExploring slides
Exploring slides
akaptur
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
FITC
 
C++totural file
C++totural fileC++totural file
C++totural file
halaisumit
 
Ruby on rails tips
Ruby  on rails tipsRuby  on rails tips
Ruby on rails tips
BinBin 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 2018
Mitchell Tilbrook
 
JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdf
Anton Arhipov
 
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 Way
tdc-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 Programming
Paul Solt
 
Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android Developers
Hassan Abid
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
Richard 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 2016
Jeff 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 ClojureScript
Ivan Bokii
 
つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~つくってあそぼ Kotlin DSL ~拡張編~
つくってあそぼ Kotlin DSL ~拡張編~
kamedon39
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard 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+k
Fabio Collini
 
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
IvanZawPhyo
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
AzharFauzan9
 
Arrays
ArraysArrays
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in Haskell
Hiromi 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
 
JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdf
 
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
 
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
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
 
Arrays
ArraysArrays
Arrays
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in Haskell
 
Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?Что нам готовит грядущий C#7?
Что нам готовит грядущий C#7?
 

Recently uploaded

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
AstuteBusiness
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
Miro Wengner
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
Intelisync
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
Javier Junquera
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 

Recently uploaded (20)

Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 

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