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

Top 10 Kotlin Stack Overflow Questions (Google I/O Extended 2018 Budapest)

Top 10 Kotlin Stack Overflow Questions (Google I/O Extended 2018 Budapest)

A selection of some of the most frequent questions about Kotlin on Stack Overflow, asked, answered and explained. Something in there for everyone, from beginners to experts.

Talk recording (Hungarian): https://youtu.be/-UMqYBoUlJc?t=4h7m38s

Marton Braun

May 08, 2018
Tweet

More Decks by Marton Braun

Other Decks in Programming

Transcript

  1. TOP 10 KOTLIN
    STACK OVERFLOW
    QUESTIONS
    Márton Szabolcs Braun
    zsmb.co zsmb13
    [email protected]

    View Slide

  2. Why do this talk?

    View Slide

  3. Why do this talk?

    View Slide

  4. Array vs
    IntArray
    What’s the difference? When do I use which one?

    View Slide

  5. Array vs IntArray

    View Slide

  6. Array vs IntArray
    Array

    View Slide

  7. Array vs IntArray
    Array Integer[]

    View Slide

  8. Array vs IntArray
    Array Integer[]
    val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

    View Slide

  9. Array vs IntArray
    Array Integer[]
    IntArray
    val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

    View Slide

  10. Array vs IntArray
    Array Integer[]
    IntArray int[]
    val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

    View Slide

  11. Array vs IntArray
    Array Integer[]
    IntArray int[]
    val intArray: IntArray = intArrayOf(1, 2, 3, 4, 5)
    val arrayOfInts: Array = arrayOf(1, 2, 3, 4, 5)

    View Slide

  12. Array vs IntArray

    View Slide

  13. Array vs IntArray
    • IntArray

    View Slide

  14. Array vs IntArray
    • IntArray
     Avoids boxing

    View Slide

  15. Array vs IntArray
    • IntArray
     Avoids boxing
     Easier to initialize
    val intArray = IntArray(10)
    val arrayOfInts = Array(5) { i -> i * 2 }

    View Slide

  16. Array vs IntArray
    • IntArray
     Avoids boxing
     Easier to initialize
    • Array
    val intArray = IntArray(10)
    val arrayOfInts = Array(5) { i -> i * 2 }

    View Slide

  17. Array vs IntArray
    • IntArray
     Avoids boxing
     Easier to initialize
    • Array
     Might be required by an API
    val intArray = IntArray(10)
    val arrayOfInts = Array(5) { i -> i * 2 }

    View Slide

  18. Array vs IntArray
    • IntArray
     Avoids boxing
     Easier to initialize
    • Array
     Might be required by an API
     Can store nullable values
    val intArray = IntArray(10)
    val arrayOfInts = Array(5) { i -> i * 2 }
    val notPeople: Array = arrayOfNulls(13)

    View Slide

  19. Iterable vs
    Sequence
    What’s the difference? When do I use which one?

    View Slide

  20. Iterable vs Sequence

    View Slide

  21. Iterable vs Sequence
    Iterable

    View Slide

  22. Iterable vs Sequence
    Iterable java.lang.Iterable

    View Slide

  23. Iterable vs Sequence
     Eager evaluation
    Iterable java.lang.Iterable

    View Slide

  24. Iterable vs Sequence
     Eager evaluation
    Iterable java.lang.Iterable
    val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)

    View Slide

  25. Iterable vs Sequence

    View Slide

  26. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  27. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  28. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  29. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  30. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  31. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  32. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  33. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  34. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  35. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  36. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  37. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  38. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  39. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  40. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  41. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  42. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  43. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  44. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  45. val people: List = getPeople()
    val allowedEntrance = people
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    Iterable vs Sequence

    View Slide

  46. Iterable vs Sequence

    View Slide

  47. Iterable vs Sequence
    Sequence

    View Slide

  48. Iterable vs Sequence
    Sequence
     Lazy evaluation

    View Slide

  49. Iterable vs Sequence
    Sequence
     Lazy evaluation
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  50. Iterable vs Sequence
    Sequence
     Lazy evaluation
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  51. Iterable vs Sequence

    View Slide

  52. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  53. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  54. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  55. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  56. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  57. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  58. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  59. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  60. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  61. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  62. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  63. Iterable vs Sequence
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  64. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  65. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  66. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  67. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  68. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  69. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  70. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  71. Iterable vs Sequence
    val people: List = getPeople()
    val allowedEntrance = people.asSequence()
    .filter { it.age >= 21 }
    .map { it.name }
    .take(5)
    .toList()

    View Slide

  72. Iterable vs Sequence

    View Slide

  73. Iterable vs Sequence
    • Iterable

    View Slide

  74. Iterable vs Sequence
    • Iterable
     Use by default

    View Slide

  75. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice

    View Slide

  76. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice
    • Sequence

    View Slide

  77. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice
    • Sequence
     To handle an infinite number of elements

    View Slide

  78. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice
    • Sequence
     To handle an infinite number of elements
     For huge collections, judiciously

    View Slide

  79. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice
    • Sequence
     To handle an infinite number of elements
     For huge collections, judiciously
    • Stream

    View Slide

  80. Iterable vs Sequence
    • Iterable
     Use by default
     Usually the best choice
    • Sequence
     To handle an infinite number of elements
     For huge collections, judiciously
    • Stream
     When interoperating with Java

    View Slide

  81. Iteration
    How can / should I iterate over collections?

    View Slide

  82. Iteration

    View Slide

  83. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }

    View Slide

  84. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }

    View Slide

  85. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }

    View Slide

  86. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }
    for (i in args.indices) {
    println(args[i])
    }

    View Slide

  87. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }
    for (i in args.indices) {
    println(args[i])
    }
    for (arg in args) {
    println(arg)
    }

    View Slide

  88. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }
    for (i in args.indices) {
    println(args[i])
    }
    for (arg in args) {
    println(arg)
    }
    args.forEach { arg ->
    println(arg)
    }

    View Slide

  89. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }
    for (i in args.indices) {
    println(args[i])
    }
    for (arg in args) {
    println(arg)
    }
    args.forEach { arg ->
    println(arg)
    }

    View Slide

  90. Iteration
    for (i in 0..args.size - 1) {
    println(args[i])
    }
    for (i in 0..args.lastIndex) {
    println(args[i])
    }
    for (i in 0 until args.size) {
    println(args[i])
    }
    for (i in args.indices) {
    println(args[i])
    }
    for (arg in args) {
    println(arg)
    }
    args.forEach { arg ->
    println(arg)
    }

    View Slide

  91. SAM conversions
    What are SAM conversions?

    View Slide

  92. SAM conversions

    View Slide

  93. SAM conversions
    public interface OnClickListener {
    void onClick(Button button);
    }

    View Slide

  94. SAM conversions
    public interface OnClickListener {
    void onClick(Button button);
    }
    public class Button {
    public void setListener(OnClickListener listener) {
    ...
    }
    }

    View Slide

  95. SAM conversions

    View Slide

  96. SAM conversions
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    println("Clicked!")
    }
    })

    View Slide

  97. SAM conversions
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    println("Clicked!")
    }
    })
    button.setListener {
    println("Clicked!")
    }

    View Slide

  98. SAM conversions
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    println("Clicked!")
    }
    })
    button.setListener {
    println("Clicked!")
    }

    View Slide

  99. SAM conversions
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    println("Clicked!")
    }
    })
    button.setListener { button: Button? ->
    println("Clicked!")
    }

    View Slide

  100. SAM conversions #1
    Why are my listeners not being called?

    View Slide

  101. SAM conversions #1
    button.setListener {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }

    View Slide

  102. SAM conversions #1
    button.setListener {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }

    View Slide

  103. SAM conversions #1
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }
    })

    View Slide

  104. SAM conversions #1
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    val listener = object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }
    })

    View Slide

  105. SAM conversions #1
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    val listener = object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    listener.onClick(...)
    }
    })

    View Slide

  106. SAM conversions #1
    button.setListener(object : OnClickListener {
    override fun onClick(button: Button?) {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }
    })

    View Slide

  107. SAM conversions #1
    button.setListener {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }

    View Slide

  108. SAM conversions #1
    button.setListener {
    object : OnClickListener {
    override fun onClick(button: Button) {
    println("Clicked!")
    }
    })
    }
    button.setListener {
    fun onClick(button: Button) {
    println("Clicked!")
    }
    }

    View Slide

  109. SAM conversions #2
    Why am I getting a return type error?

    View Slide

  110. SAM conversions #2
    public interface OnClickListener {
    void onClick(Button button);
    }

    View Slide

  111. SAM conversions #2
    public interface OnClickListener {
    boolean onClick(Button button);
    }

    View Slide

  112. SAM conversions #2
    public interface OnClickListener {
    boolean onClick(Button button);
    }
    button.setListener {
    println("Clicked!")
    }

    View Slide

  113. SAM conversions #2
    public interface OnClickListener {
    boolean onClick(Button button);
    }
    button.setListener {
    println("Clicked!")
    }
    Kotlin: Type mismatch: inferred type is Unit but
    Boolean was expected

    View Slide

  114. SAM conversions #2
    public interface OnClickListener {
    boolean onClick(Button button);
    }
    button.setListener {
    println("Clicked!")
    true
    }

    View Slide

  115. SAM conversions #2
    public interface OnClickListener {
    boolean onClick(Button button);
    }
    button.setListener {
    println("Clicked!")
    true
    }

    View Slide

  116. Replacing statics
    How do I create static functions and variables in Kotlin?

    View Slide

  117. Replacing statics
    class Foo {
    companion object {
    fun x() { ... }
    }
    fun y() { ... }
    }

    View Slide

  118. Replacing statics
    class Foo {
    companion object {
    fun x() { ... }
    }
    fun y() { ... }
    }
    Foo.x()

    View Slide

  119. Replacing statics
    class Foo {
    companion object {
    fun x() { ... }
    }
    fun y() { ... }
    }
    object Foo {
    fun x() { ... }
    }
    Foo.x()
    Foo.x()

    View Slide

  120. Replacing statics
    class Foo {
    companion object {
    fun x() { ... }
    }
    fun y() { ... }
    }
    object Foo {
    fun x() { ... }
    }
    fun x() { ... }
    Foo.x()
    Foo.x()
    x()

    View Slide

  121. Replacing statics
    class Foo {
    companion object {
    fun x() { ... }
    }
    fun y() { ... }
    }
    object Foo {
    fun x() { ... }
    }
    fun x() { ... }
    Foo.x()
    Foo.x()
    x()

    View Slide

  122. Function declaration reference
    Declaration Kotlin usage Java usage
    Companion object Foo.f() Foo.Companion.f();
    Companion object with @JvmStatic Foo.f() Foo.f();
    Object Foo.f() Foo.INSTANCE.f();
    Object with @JvmStatic Foo.f() Foo.f();
    Top level function f() UtilKt.f();
    Top level function with @JvmName* f() Util.f();
    * With the @JvmName annotation on the file use-site target

    View Slide

  123. Variable declaration reference
    Declaration Kotlin usage Java usage
    Companion object X.x X.Companion.getX();
    Companion object with @JvmStatic X.x X.getX();
    Companion object with @JvmField X.x X.x;
    Companion object with const X.x X.x;
    Object X.x X.INSTANCE.getX();
    Object with @JvmStatic X.x X.getX();
    Object with @JvmField X.x X.x;
    Object with const X.x X.x;
    Top level variable x ConstKt.getX();
    Top level variable with @JvmField x ConstKt.x;
    Top level variable with const x ConstKt.x;
    Top level variable with @JvmName* x Const.getX();
    Top level variable with @JvmName* and @JvmField x Const.x;
    Top level variable with @JvmName* and const x Const.x;
    * With the @JvmName annotation on the file use-site target

    View Slide

  124. Smart casts on
    mutable properties
    Why are smart casts not working?

    View Slide

  125. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    if (toy != null) {
    toy.chew()
    }
    }
    }

    View Slide

  126. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    if (toy != null) {
    toy.chew()
    }
    }
    }
    Kotlin: Smart cast to 'Toy' is impossible, because 'toy' is
    a mutable property that could have been changed by this time

    View Slide

  127. Smart casts on mutable properties
    class Dog(val toy: Toy? = null) {
    fun play() {
    if (toy != null) {
    toy.chew()
    }
    }
    }

    View Slide

  128. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    if (toy != null) {
    toy.chew()
    }
    }
    }

    View Slide

  129. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    val _toy = toy
    if (_toy != null) {
    _toy.chew()
    }
    }
    }

    View Slide

  130. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    toy?.let {
    it.chew()
    }
    }
    }

    View Slide

  131. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    toy?.chew()
    }
    }

    View Slide

  132. Smart casts on mutable properties
    class Dog(var toy: Toy? = null) {
    fun play() {
    toy?.let {
    it.chew()
    it.chew()
    it.chew()
    }
    }
    }

    View Slide

  133. null!!
    Why am I getting NullPointerExceptions?

    View Slide

  134. null!!

    View Slide

  135. null!!
    class Episode {
    var airdate: Date = null!!
    }

    View Slide

  136. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }

    View Slide

  137. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date?

    View Slide

  138. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    WeekDay
    Date?

    View Slide

  139. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date
    WeekDay
    Date?

    View Slide

  140. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date

    View Slide

  141. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date date as Date

    View Slide

  142. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date date as Date
    throw NullPointerException()

    View Slide

  143. null!!
    class Episode {
    var airdate: Date = null!!
    }
    fun getWeekDay(date: Date?): WeekDay {
    return date!!.getWeekDay()
    }
    Date

    View Slide

  144. null!!
    class Episode {
    var airdate: Date = null!!
    }

    View Slide

  145. null!!
    class Episode {
    var airdate: Date = null!!
    }

    View Slide

  146. null!!
    class Episode {
    var airdate: Date = throw KotlinNullPointerException()
    }

    View Slide

  147. null!!
    class Episode {
    lateinit var airdate: Date
    }

    View Slide

  148. Platform types in
    overrides
    How do I choose the right type when overriding Java methods?

    View Slide

  149. Platform types in overrides

    View Slide

  150. Platform types in overrides
    public interface OnClickListener {
    void onClick(Button button);
    }

    View Slide

  151. Platform types in overrides
    public interface OnClickListener {
    void onClick(Button button);
    }
    class KtListener : OnClickListener {
    override fun onClick(button: Button?): Unit {
    val name = button?.name ?: "Unknown button"
    println("Clicked ${name}")
    }
    }

    View Slide

  152. Platform types in overrides
    public interface OnClickListener {
    void onClick(Button button);
    }
    class KtListener : OnClickListener {
    override fun onClick(button: Button?): Unit {
    val name = button?.name ?: "Unknown button"
    println("Clicked ${name}")
    }
    }

    View Slide

  153. Platform types in overrides
    public interface OnClickListener {
    void onClick(Button button);
    }
    class KtListener : OnClickListener {
    override fun onClick(button: Button?): Unit {
    val name = button?.name ?: "Unknown button"
    println("Clicked ${name}")
    }
    }

    View Slide

  154. Platform types in overrides
    public interface OnClickListener {
    void onClick(Button button);
    }
    class KtListener : OnClickListener {
    override fun onClick(button: Button): Unit {
    val name = button.name
    println("Clicked ${name}")
    }
    }

    View Slide

  155. Import aliases
    What can I do about imports with conflicting names?

    View Slide

  156. Import aliases

    View Slide

  157. Import aliases
    package com.example.code
    fun indent(str: String)
    : String { ... }
    package com.example.square
    fun indent(str: String)
    : String { ... }

    View Slide

  158. Import aliases
    package com.example.code
    fun indent(str: String)
    : String { ... }
    package com.example.square
    fun indent(str: String)
    : String { ... }
    import com.example.code.indent
    indent("hello")
    com.example.square.indent("world")

    View Slide

  159. Import aliases
    package com.example.code
    fun String.indent()
    : String { ... }
    package com.example.square
    fun String.indent()
    : String { ... }

    View Slide

  160. Import aliases
    package com.example.code
    fun String.indent()
    : String { ... }
    package com.example.square
    fun String.indent()
    : String { ... }
    import com.example.code.indent
    "hello".indent()
    "world".indent()

    View Slide

  161. Import aliases
    package com.example.code
    fun String.indent()
    : String { ... }
    package com.example.square
    fun String.indent()
    : String { ... }
    import com.example.code.indent as indent4
    import com.example.square.indent as indent2
    "hello".indent4()
    "world".indent2()

    View Slide

  162. Import aliases
    import java.util.Date as UtilDate
    import java.sql.Date as SqlDate
    fun matches(date1: UtilDate, date2: SqlDate): Boolean {
    ...
    }

    View Slide

  163. Kotlin vs Java for
    Android development
    Please help I just started

    View Slide

  164. Kotlin vs Java for Android development

    View Slide

  165. Kotlin vs Java for Android development

    View Slide

  166. Recap
    • 1. Array vs IntArray
    • 2. Iterable vs Sequence
    • 3. Iteration
    • 4. SAM conversions
    • 5. Replacing statics
    • 6. Smart casts on mutable properties
    • 7. null!!
    • 8. Platform types in overrides
    • 9. Import aliases
    • 10. Kotlin vs Java for Android development

    View Slide

  167. References
    • Top 10 Kotlin Stack Overflow questions, article series
     https://zsmb.co/top-10-kotlin-stack-overflow-questions-1/
    • Kotlin tag on Stack Overflow
     https://stackoverflow.com/questions/tagged/kotlin

    View Slide

  168. Photo:
    Alexey Sergeev
    Questions?
    zsmb.co zsmb13
    [email protected]

    View Slide