Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin - Not you grandfather's Java

Kotlin - Not you grandfather's Java

Introduction to Kotlin, for Java developers.

Presented on March 30th 2017 for the Portuguese Java User Group, at Talkdesk's Lisbon Office.

João Carvalho

March 30, 2017
Tweet

More Decks by João Carvalho

Other Decks in Programming

Transcript

  1. Kotlin:
    Not your grandfather’s Java
    João Carvalho - @johnkarva - PT.JUG

    View Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. What is Kotlin?

    View Slide

  6. View Slide

  7. View Slide

  8. https://try.kotlinlang.org

    View Slide

  9. Philosophy

    View Slide

  10. Pragmatic

    View Slide

  11. Concise

    View Slide

  12. Safe

    View Slide

  13. Interoperable

    View Slide

  14. Tooling

    View Slide

  15. Lightweight
    868KB runtime

    View Slide

  16. View Slide

  17. public class HelloWorld {
    public static void main(String... args) {
    System.out
    .println("Hello world " + args[0]);
    }
    }

    View Slide

  18. fun main(args: Array) {
    println("Hello world ${args[0]}")
    }

    View Slide

  19. Types

    View Slide

  20. public void printName(Person person) {
    System.out.println(person.getName());
    }

    View Slide

  21. public void printName(Person person) {
    System.out.println(person.getName());
    }
    null

    View Slide

  22. View Slide

  23. fun printName(person: Person) {
    println(person.name)
    }

    View Slide

  24. printName(null)
    ERROR: Null cannot be a value of
    non-null type Person.

    View Slide

  25. fun printName(person: Person?) {
    if (person != null) {
    println(person.name)
    }
    }

    View Slide

  26. Primitive Types

    View Slide

  27. Arrays

    View Slide

  28. Variables

    View Slide

  29. final String name = "Kotlin";
    int age = 5;
    // A few moments later
    age = 6;

    View Slide

  30. val name: String = "Kotlin"
    var age: Int = 5
    // A few moments later
    age = 6

    View Slide

  31. val name = "Kotlin"
    var age = 5
    // A few moments later
    age = 6

    View Slide

  32. Functions/Expressions

    View Slide

  33. fun max(one: Int, other: Int): Int {
    if (one > other) {
    return one
    } else {
    return other
    }
    }

    View Slide

  34. fun max(one: Int, other: Int): Int {
    return if (one > other) {
    one
    } else {
    other
    }
    }

    View Slide

  35. fun max(one: Int, other: Int): Int =
    if (one > other) {
    one
    } else {
    other
    }

    View Slide

  36. fun max(one: Int, other: Int) =
    if (one > other) {
    one
    } else {
    other
    }

    View Slide

  37. fun max(one: Int, other: Int) =
    if (one > other) one else other

    View Slide

  38. Operators

    View Slide

  39. when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
    print("x is neither 1 nor 2")
    }
    }

    View Slide

  40. Safe Navigation

    View Slide

  41. private String safeGetName(Person person) {
    return person == null ? null :
    person.getName();
    }

    View Slide

  42. fun safeGetName(person: Person?): String? {
    return person?.name
    }

    View Slide

  43. Elvis Operator

    View Slide

  44. fun printName(person: Person?) {
    println("Name is ${person?.name
    ?: "Unknown"}")
    }

    View Slide

  45. Smart Casts

    View Slide

  46. fun printStringLength(any: Any) {
    if (any is String) {
    println("Length is ${any.length}")
    } else {
    return println("Oops, not a String")
    }
    }

    View Slide

  47. fun printStringLength(any: Any) {
    val asString = any as String
    println("Length is ${asString.length}")
    }

    View Slide

  48. fun printStringLength(any: Any) {
    val asString = any as? String
    println("Length is ${asString?.length
    ?: "Unknown"}")
    }

    View Slide

  49. Classes

    View Slide

  50. class Person {
    }

    View Slide

  51. Final/Public by default

    View Slide

  52. Constructors

    View Slide

  53. class Fooer(name: String) {
    init {
    println("Setting up to foo $name")
    }
    }

    View Slide

  54. class Fooer(name: String) {
    init {
    println("Setting up to foo $name")
    }
    constructor(name: String, option: String) : this(name) {
    println("\tUsing option $option")
    }
    }

    View Slide

  55. Inheritance

    View Slide

  56. open class Bar
    class Foo : Bar() {
    }

    View Slide

  57. Properties

    View Slide

  58. class Fooer(name: String) {
    private val name: String
    init {
    this.name = name
    }
    }

    View Slide

  59. class Fooer(private val name: String)

    View Slide

  60. private var name: String = ""
    get() {
    println("Returning $name")
    return name
    }

    View Slide

  61. var name: String = ""
    private set

    View Slide

  62. Delegated Properties

    View Slide

  63. class Example {
    var p: String by Delegate()
    }

    View Slide

  64. val lazyValue: String by lazy {
    println("computed!")
    "Hello"
    }

    View Slide

  65. var name: String by
    Delegates.observable("") {
    _, old, new ->
    println("$old -> $new")
    }

    View Slide

  66. Extension Functions

    View Slide

  67. fun String.helloize() = "Hello $this"
    "World".helloize()

    View Slide

  68. Data classes

    View Slide

  69. public class Person {
    private String name;
    private int age;
    (...)
    }

    View Slide

  70. public Person(String name, int age) {
    this.name = name;
    this.age = age;
    }

    View Slide

  71. public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }

    View Slide

  72. @Override
    public boolean equals(Object o) {
    (Stuff generated by your IDE)
    }
    @Override
    public int hashCode() {
    int result = name.hashCode();
    result = 31 * result + age;
    return result;
    }

    View Slide

  73. @Override
    public String toString() {
    return "Person{" +
    "name='" + name + '\'' +
    ", age=" + age +
    '}';
    }

    View Slide

  74. View Slide

  75. data class Person(var name: String,
    var age: Int)

    View Slide

  76. val john = Person("John", 21)

    View Slide

  77. Immutable?

    View Slide

  78. private final String name;
    public Person withName(String name) {
    return new Person(name, this.age);
    }

    View Slide

  79. data class Person(var name: String,
    var age: Int)

    View Slide

  80. data class Person(val name: String,
    val age: Int)

    View Slide

  81. val john = Person("John", 21)
    val olderJohn = john.copy(age = 78)

    View Slide

  82. Named Arguments

    View Slide

  83. public class Person {
    public Person(String name,
    String lastName,
    int age,
    Instant birthDate,
    (...))
    }

    View Slide

  84. new Person("John", "Doe",
    26, Instant.now(), (...));

    View Slide

  85. View Slide

  86. Person(name = "John",
    lastName = "Doe",
    age = 26,
    birthDate = Instant.now())

    View Slide

  87. Default Values

    View Slide

  88. View Slide

  89. class BCryptPasswordEncoder(
    private val strength: Int = -1,
    private val random: SecureRandom = SecureRandom()
    )

    View Slide

  90. Collections

    View Slide

  91. Mutable vs Immutable

    View Slide

  92. emptyList()
    listOf(1, 2, 3)
    mutableListOf(1, 2, 3)
    emptySet()
    setOf("John", "Jane")
    mutableSetOf("John", "Jane")
    emptyMap()
    mapOf("John" to "Doe")
    mutableMapOf("John" to "Doe")

    View Slide

  93. Utilities

    View Slide

  94. // apply
    BaseClientDetails().apply {
    clientId = "foo"
    }
    // takeIf
    userRepository.findOne("foo")?.takeIf(User::active)
    // use
    inputStream.use {
    it.read()
    }
    // let
    clientId?.let { loadClient(it) }

    View Slide

  95. Going Functional

    View Slide

  96. Higher-Order Functions

    View Slide

  97. fun doWithinLock(lock: Lock,
    body: () -> T): T {
    lock.lock()
    try {
    return body()
    }
    finally {
    lock.unlock()
    }
    }

    View Slide

  98. doWithinLock(lock) {
    println("Hello lock")
    }

    View Slide

  99. map.map { (key, value) ->
    "$key$value"
    }

    View Slide

  100. Functions with Receiver

    View Slide

  101. class HTML {
    var value = ""
    fun body(value: String) { this.value = value }
    }
    fun html(init: HTML.() -> Unit) = HTML().apply {
    init()
    }
    html {
    body("Hello world")
    }

    View Slide

  102. Questions?

    View Slide