Slide 1

Slide 1 text

Seamless Kotlin / Java Interop

Slide 2

Slide 2 text

HELLO! I am Pamela Hill Android Engineer @ Luno You can find me at @pamelaahill or pamelaahill.com 2

Slide 3

Slide 3 text

Topics ▹ Quick Kotlin 101 ▹ Why interop matters ▹ Kotlin → Java ▹ Java → Kotlin ▹ Q&A 3

Slide 4

Slide 4 text

1. Quick Kotlin 101

Slide 5

Slide 5 text

We’re all still learning something 5

Slide 6

Slide 6 text

6 Declaring a variable val PI = 3.14 var radius = 13.0 • Forced to think of immutability vs mutability • Nudge toward favouring immutability

Slide 7

Slide 7 text

7 Type inference val isSquare = false val area = 12.5 • The compiler is smart! • Type declarations only when cannot infer

Slide 8

Slide 8 text

8 Declaring a function fun plus(i: Int, j: Int): Int { return i + j } fun plus(i: Int, j: Int) = i + j • Expression body- one statement • Block bodies - more than one

Slide 9

Slide 9 text

9 Top-level functions and variables val PI = 3.14 fun plus(i: Int, j: Int) = i + j • Removes need for utilities classes

Slide 10

Slide 10 text

10 Named arguments fun plus(i: Int, j: Int) = i + j … plus(i = 1, j = 2) • Improves readability for long argument lists • Adds context

Slide 11

Slide 11 text

11 Nullability val width : Double = 4.0 val length : Double = 5.0 val height : Double? = null • Once possibly null, always possibly null • Guards against dreaded NPE

Slide 12

Slide 12 text

12 Data classes data class Rectangle (val width: Double, val height: Double) • Accessors, mutators, equals, hashCode, toString, copy implied • Concise, readable

Slide 13

Slide 13 text

13 Inheritance open class Rectangle (val width: Double, val height: Double) class Square (width: Double): Rectangle(width, width) • Need to open classes/functions for inheritance/overriding • Helps with fragile base class problem

Slide 14

Slide 14 text

14 Lambdas & higher-order functions val calculator = { i: Int, j: Int -> i + j} fun printCalculation (calc: (Int, Int) -> Int){ println("${calc(1, 2)}") } • Arrow library for more advanced features

Slide 15

Slide 15 text

15 Extension functions class Rectangle (val width: Double, val height: Double) … fun Rectangle.calcArea () = width * height … Rectangle(1,2).calcArea() • Alter existing classes without changing code

Slide 16

Slide 16 text

2. Why interop matters

Slide 17

Slide 17 text

Things can get a little freaky… 17

Slide 18

Slide 18 text

18 To whom should it matter? • Java library developers • Kotlin library developers • Mixed/migrating codebase developers

Slide 19

Slide 19 text

19 What should we aim for? • Safety • Readability • Performance

Slide 20

Slide 20 text

3. Kotlin → Java

Slide 21

Slide 21 text

Because the ecosystem is like Christmas 21

Slide 22

Slide 22 text

22 Don’t use hard keywords • object, in, is are keywords in Kotlin, but not Java • Kotlin will be forced to back-tick eg. `is`

Slide 23

Slide 23 text

23 Use nullability annotations • Every parameter, return, field should have a nullability annotation • Eg. @NotNull or @Nullable • Different annotation sets supported

Slide 24

Slide 24 text

24 Lambda parameters last fun calculation(x: Int, y: Int, calc: (Int, Int) -> Int) = calc(x,y) ... calculation( 3, 4) { i, j -> i * j } • Natural reading style, great for DSLs

Slide 25

Slide 25 text

25 Bean standards for properties class Rectangle { private int width = 0; public int getWidth() {…} public void setWidth(int width){…} } rectangle.width = 2; println("${rectangle.width}")

Slide 26

Slide 26 text

4. Java → Kotlin

Slide 27

Slide 27 text

Mixed codebases happen 27

Slide 28

Slide 28 text

28 Files with top-level functions and variables In file CalcUtils.kt: fun calculation(x: Int, y: Int) = x * y CalcUtilsKt.calculation(3, 4)

Slide 29

Slide 29 text

29 Files with top-level functions and variables In file CalcUtils.kt: @file:JvmName("CalcUtils") fun calculation(x: Int, y: Int) = x * y CalcUtils.calculation(3, 4)

Slide 30

Slide 30 text

30 Exceptions fun parseInt(string: String) : Int { return string.toInt() } try { parseInt("abc") } catch (NumberFormatException nfe){…}

Slide 31

Slide 31 text

31 Exceptions @Throws(NumberFormatException::class) fun parseInt(string: String) : Int { return string.toInt() } try { parseInt("abc") } catch (NumberFormatException nfe){…}

Slide 32

Slide 32 text

32 Functions with defaults fun funWithDefaults(x: Int, y: Int = 0, z: Int = 0) { ... } funWithDefaults(x,0,0)

Slide 33

Slide 33 text

33 Functions with defaults @JvmOverloads fun funWithDefaults(x: Int, y: Int = 0, z: Int = 0) { ... } funWithDefaults(x) funWithDefaults(x,y) funWithDefaults(x,y,z)

Slide 34

Slide 34 text

34 Unit returns fun sayHi(callback: (String) -> Unit) = {…} greeter.sayHi(name -> { System.out.println("Hello, " + name + "!"); return Unit.INSTANCE; });

Slide 35

Slide 35 text

35 Unit returns interface GreeterCallback { fun greetName(name: String): Unit } fun sayHi(callback: GreeterCallback) = {…} greeter.sayHi(name -> System.out.println("Greeting", "Hello, " + name + “!”));

Slide 36

Slide 36 text

5. Q&A

Slide 37

Slide 37 text

I’m nice! →☝ Ask me anything about Kotlin 37

Slide 38

Slide 38 text

THANKS! You can find me at: @pamelaahill or pamelaahill.com 38

Slide 39

Slide 39 text

CREDITS Special thanks to all the people who made and released these awesome resources for free: ▹ Presentation template by SlidesCarnival ▹ Photographs by Unsplash and Pexels 39