Save 37% off PRO during our Black Friday Sale! »

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.

Eb987f4f2b2d43faa8b3b5a377713913?s=128

João Carvalho

March 30, 2017
Tweet

Transcript

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

    PT.JUG
  2. None
  3. None
  4. None
  5. What is Kotlin?

  6. None
  7. None
  8. https://try.kotlinlang.org

  9. Philosophy

  10. Pragmatic

  11. Concise

  12. Safe

  13. Interoperable

  14. Tooling

  15. Lightweight 868KB runtime

  16. None
  17. public class HelloWorld { public static void main(String... args) {

    System.out .println("Hello world " + args[0]); } }
  18. fun main(args: Array<String>) { println("Hello world ${args[0]}") }

  19. Types

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

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

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

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

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

    } }
  26. Primitive Types

  27. Arrays

  28. Variables

  29. final String name = "Kotlin"; int age = 5; //

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

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

    few moments later age = 6
  32. Functions/Expressions

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

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

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

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

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

    one else other
  38. Operators

  39. when (x) { 1 -> print("x == 1") 2 ->

    print("x == 2") else -> { print("x is neither 1 nor 2") } }
  40. Safe Navigation

  41. private String safeGetName(Person person) { return person == null ?

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

  43. Elvis Operator

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

  45. Smart Casts

  46. fun printStringLength(any: Any) { if (any is String) { println("Length

    is ${any.length}") } else { return println("Oops, not a String") } }
  47. fun printStringLength(any: Any) { val asString = any as String

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

    println("Length is ${asString?.length ?: "Unknown"}") }
  49. Classes

  50. class Person { }

  51. Final/Public by default

  52. Constructors

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

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

    $name") } constructor(name: String, option: String) : this(name) { println("\tUsing option $option") } }
  55. Inheritance

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

  57. Properties

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

    this.name = name } }
  59. class Fooer(private val name: String)

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

    return name }
  61. var name: String = "" private set

  62. Delegated Properties

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

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

  65. var name: String by Delegates.observable("<Unknown>") { _, old, new ->

    println("$old -> $new") }
  66. Extension Functions

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

  68. Data classes

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

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

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

    name) { this.name = name; }
  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; }
  73. @Override public String toString() { return "Person{" + "name='" +

    name + '\'' + ", age=" + age + '}'; }
  74. None
  75. data class Person(var name: String, var age: Int)

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

  77. Immutable?

  78. private final String name; public Person withName(String name) { return

    new Person(name, this.age); }
  79. data class Person(var name: String, var age: Int)

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

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

    78)
  82. Named Arguments

  83. public class Person { public Person(String name, String lastName, int

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

  85. None
  86. Person(name = "John", lastName = "Doe", age = 26, birthDate

    = Instant.now())
  87. Default Values

  88. None
  89. class BCryptPasswordEncoder( private val strength: Int = -1, private val

    random: SecureRandom = SecureRandom() )
  90. Collections

  91. Mutable vs Immutable

  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")
  93. Utilities

  94. // apply BaseClientDetails().apply { clientId = "foo" } // takeIf

    userRepository.findOne("foo")?.takeIf(User::active) // use inputStream.use { it.read() } // let clientId?.let { loadClient(it) }
  95. Going Functional

  96. Higher-Order Functions

  97. fun <T> doWithinLock(lock: Lock, body: () -> T): T {

    lock.lock() try { return body() } finally { lock.unlock() } }
  98. doWithinLock(lock) { println("Hello lock") }

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

  100. Functions with Receiver

  101. class HTML { var value = "" fun body(value: String)

    { this.value = value } } fun html(init: HTML.() -> Unit) = HTML().apply { init() } html { body("Hello world") }
  102. Questions?