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

Kotlin-Workshop Day #3

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Kotlin-Workshop Day #3

Android Academy TLV - Kotlin workshop day #3

Co-created with
Eden Bugdary Machluf and Hadas Peled

Avatar for Gil Goldzweig

Gil Goldzweig

October 17, 2019
Tweet

More Decks by Gil Goldzweig

Other Decks in Programming

Transcript

  1. by Hadas Peled, Gil Goldzweig Goldbaum, Eden Bugdary Machluf Shmupidoo

    17/10/19 WIFI: Guest Password: BrokenWires@@2019 1
  2. 2

  3. ▢ More classes: ❏ Inheritance ❏ Abstract ❏ Interfaces ▢

    Data class ▢ Special classes ▢ Pairs ▢ Collections ▢ Constants ▢ Extensions & infix 3
  4. ▢ Generics ▢ Higher - Order functions ▢ Inline functions

    ▢ Java interoperability ▢ Labeled breaks ▢ Reflection ▢ Tips & Tricks 4
  5. 5

  6. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 6
  7. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 7
  8. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 8
  9. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 9
  10. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 10
  11. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 11
  12. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 12
  13. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } val intList: MyIntList 13
  14. class MyIntList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 14
  15. class MyStringList { fun get(pos: Int): Int { //returns the

    item in position `pos` } fun addItem(item: Int) { //adds the new item `item` to the list } } 15
  16. class MyStringList { fun get(pos: Int): String { //returns the

    item in position `pos` } fun addItem(item: String) { //adds the new item `item` to the list } } 16
  17. 17

  18. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } 18
  19. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } 19
  20. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } 20
  21. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } 21
  22. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } val intList: MyList<Int> 22
  23. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } val intList: MyList<Int> 23
  24. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } val intList: MyList<Int> 24
  25. class MyList<T> { fun get(pos: Int): T { //returns the

    item in position `pos` } fun addItem(item: T) { //adds the new item `item` to the list } } val intList: MyList<Int> val stringList: MyList<String> 25
  26. 26

  27. 33

  28. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T>(val

    snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? 41
  29. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T>(val

    snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? var nullRefreshments = Refreshments(null) //why?? 42
  30. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T>(val

    snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? var nullRefreshments = Refreshments(null) //why?? 43
  31. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Any?>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? var nullRefreshments = Refreshments(null) //why?? 44
  32. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Any>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? var nullRefreshments = Refreshments(null) //why?? 45
  33. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Any>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? var nullRefreshments = Refreshments(null) //why?? 46
  34. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Any>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? 47
  35. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Any>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? 48
  36. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? 49
  37. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T) var refreshments = Refreshments(TimTam()) var stringRefreshments = Refreshments(“String”) //why?? 50
  38. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 52
  39. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 53
  40. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 54
  41. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 55
  42. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 56
  43. open class Snack(var needsContainer: Boolean) class TimTam: Snack(false) class Refreshments<T:

    Snack>(val snack: T){ fun waitAtTable(){ check(!snack.needsContainer){"can't serve $snack!"} println("$snack is served") } } 57
  44. 59

  45. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 67
  46. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 68
  47. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 69
  48. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 70
  49. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 71
  50. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 72
  51. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 73
  52. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") 75
  53. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") 76
  54. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") 77
  55. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments = Refreshments(TimTam()) 78
  56. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments: Refreshments<TimTam> = Refreshments(TimTam()) 79
  57. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments: Refreshments<TimTam> = Refreshments(TimTam()) addItemTo(refreshments) 80
  58. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments: Refreshments<TimTam> = Refreshments(TimTam()) addItemTo(refreshments) Type mismatch: inferred type is Refreshments<TimTam> but Refreshments<Snack> was expected 81
  59. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 82
  60. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 83
  61. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 84
  62. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 85
  63. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 86
  64. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 87
  65. Scarry word Key word What it actually means Invariance var

    snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments: Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments: Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Snack 88
  66. Rules that prevent us from getting an error • Out

    type - type parameters that only ever occur in return values of functions, or on val properties. 91
  67. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments = Refreshments(TimTam()) 92
  68. class Refreshments<T: Snack>(val snack: T) { fun waitAtTable() { check(!snack.needsContainer)

    {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments = Refreshments(TimTam()) 93
  69. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable() {

    check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments = Refreshments(TimTam()) 94
  70. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable() {

    check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } fun addItemTo(ref: Refreshments<Snack>) = println("item added") val refreshments = Refreshments(TimTam()) addItemTo(refreshments) 95
  71. 96

  72. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) interface Container<T:

    Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 103
  73. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) interface Container<T:

    Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 104
  74. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) interface Container<T:

    Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 105
  75. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) interface Container<T:

    Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 106
  76. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) interface Container<T:

    Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 107
  77. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) { fun

    getBowl() { needsContainer = false } } interface Container<T: Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 108
  78. open class Snack(var needsContainer: Boolean) class Doritos: Snack(true) { fun

    getBowl() { needsContainer = false } } interface Container<T: Snack> { fun contain(snack: T) } class Bowler: Container<Doritos> { override fun contain(doritos: Doritos) { doritos.getBowl() } } 109
  79. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable() {

    check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } 110
  80. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable() {

    check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } 111
  81. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } 112
  82. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } Type parameter T is declared as 'out' but occurs in 'invariant' position in type Container<T> 113
  83. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 114
  84. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 115
  85. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } 116
  86. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } 117
  87. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } 118
  88. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } 119
  89. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } Snack 120
  90. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) fun spillSnack(): T } 121
  91. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<out T: Snack> { fun contain(snack: T) fun spillSnack(): T } 122
  92. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { val snackBrother: T = container.spillSnack() check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<out T: Snack> { fun contain(snack: T) fun spillSnack(): T } Type parameter T is declared as 'out' but occurs in 'in' position in type Container<T> 123
  93. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 124
  94. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 125
  95. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 126
  96. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 127
  97. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 128
  98. Scarry word Key word What it actually means Invariance var

    snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Covariance out var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //WORK var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //ERROR Contravariance in var snackRefreshments :Refreshments<Snack> = Refreshments<TimTam>(TimTam()) //ERROR var timtamRefreshments :Refreshments<TimTam> = Refreshments<Snack>(Snack(false)) //WORK Snack 129
  99. Rules that prevent us from getting an error • Out

    type - type parameters that only ever occur in return values of functions, or on val properties. 131
  100. Rules that prevent us from getting an error • Out

    type - type parameters that only ever occur in return values of functions, or on val properties. • In type - type parameters that only ever occur as an argument to functions. 132
  101. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 136
  102. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { //check(!snack.needsContainer) {"can't serve $snack!"} println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 137
  103. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { //check(!snack.needsContainer) {"can't serve $snack!"} if(snack.needsContainer) { container.contain(snack) } println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 138
  104. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { //check(!snack.needsContainer) {"can't serve $snack!"} if(snack.needsContainer) { container.contain(snack) } println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 139
  105. class Refreshments<out T: Snack>(val snack: T) { fun waitAtTable(container: Container<T>)

    { //check(!snack.needsContainer) {"can't serve $snack!"} if(snack.needsContainer) { container.contain(snack) } println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } 140
  106. class Refreshments<out T: Snack>(val snack:T) { fun waitAtTable(container: Container<T>) {

    //check(!snack.needsContainer) {"can't serve $snack!"} if(snack.needsContainer) { container.contain(snack) } println("$snack is served") } } interface Container<T: Snack> { fun contain(snack: T) } Refreshments(Doritos()).waitAtTable(Bowler()) 141
  107. 142

  108. 143

  109. fun <T : Snack> isContainerNeeded(refreshment: Refreshments<T>) { println("Is container needed?

    ${refreshment.snack.needsContainer}") } isContainerNeeded(refreshment) 148
  110. fun <T : Snack> isContainerNeeded(refreshment: Refreshments<T>) { println("Is container needed?

    ${refreshment.snack.needsContainer}") } isContainerNeeded(refreshment) 149
  111. fun <T : Snack> isContainerNeeded(refreshment: Refreshments<T>) { println("Is container needed?

    ${refreshment.snack.needsContainer}") } isContainerNeeded(refreshment) 150
  112. fun <T : Snack> isContainerNeeded(refreshment: Refreshments<T>) { println("Is container needed?

    ${refreshment.snack.needsContainer}") } isContainerNeeded(refreshment) 151
  113. fun <T : Snack> isContainerNeeded(refreshment: Refreshments<T>) { println("Is container needed?

    ${refreshment.snack.needsContainer}") } isContainerNeeded(refreshment) //Is container needed? true 152
  114. 153

  115. Function: fun makeFood(hangerLevel: Int) { if (hangerLevel > 5) {

    println("Give a lot of food !") } else { println("Only a refreshment") } } 154
  116. Function: fun makeFood(hangerLevel: Int) { if (hangerLevel > 5) {

    println("Give a lot of food !") } else { println("Only a refreshment") } } 155
  117. Function: fun makeFood(hangerLevel: Int) { if (hangerLevel > 5) {

    println("Give a lot of food !") } else { println("Only a refreshment") } } 156
  118. Function: fun makeFood(hangerLevel: Int) { if (hangerLevel > 5) {

    println("Give a lot of food !") } else { println("Only a refreshment") } } 157
  119. class Refreshments<T :Snack>(val snack :T){ fun < R : Snack>

    hasRefreshmentOfType() = snack is R //.. } inline reified Generic types are normally only available at compile time, and get replaced with the actual types. 163
  120. inline fun <reified T: Snack> Snack.isOfType() = this is T

    var refreshment = Refreshments(Doritos()) println(refreshment.snack.isOfType<TimTam>()) 164
  121. inline fun <reified T: Snack> Snack.isOfType() = this is T

    var refreshment = Refreshments(Doritos()) println(refreshment.snack.isOfType<TimTam>()) 165
  122. inline fun <reified T: Snack> Snack.isOfType() = this is T

    var refreshment = Refreshments(Doritos()) println(refreshment.snack.isOfType<TimTam>()) 166
  123. inline fun <reified T: Snack> Snack.isOfType() = this is T

    var refreshment = Refreshments(Doritos()) println(refreshment.snack.isOfType<TimTam>()) 167
  124. inline fun <reified T: Snack> Snack.isOfType() = this is T

    var refreshment = Refreshments(Doritos()) println(refreshment.snack.isOfType<TimTam>()) //false 168
  125. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 170
  126. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 171
  127. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 172
  128. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 173
  129. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 174
  130. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 175
  131. inline fun <reified R : Snack> Refreshments<*>.hasRefreshmentOfType() = snack is

    R var refreshment = Refreshments(Doritos()) println(refreshment.hasRefreshmentOfType<Doritos>()) //true 176
  132. • Kotlin functions are first-class ◦ Can be stored in

    variables and data structures ◦ passed as arguments to and returned from other functions. 178
  133. 223

  134. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 225
  135. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 226
  136. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 227
  137. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 228
  138. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 229
  139. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 230
  140. fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element in

    this) { loop(element) } } fun notInlined(elements: List<Int>) { elements.forEach { println("NoInlined: $it") } } 231
  141. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 232
  142. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 233
  143. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 234
  144. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 235
  145. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 236
  146. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 237
  147. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 238
  148. public static void notInlined(List elements) { Intrinsics.checkParameterIsNotNull(elements, "elements"); forEach(elements, new

    Function1<Int>() { @Override public void invoke(element: Int) { System.out.println("NoInlined: " + element); } }); ); } 239
  149. fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element in

    this) { loop(element) } } fun notInlined(elements: List<Int>) { elements.forEach { println("NotInlined: $it") } } 240
  150. inline fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element

    in this) { loop(element) } } fun notInlined(elements: List<Int>) { elements.forEach { println("NotInlined: $it") } } 241
  151. inline fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element

    in this) { loop(element) } } fun notInlined(elements: List<Int>) { elements.forEach { println("NotInlined: $it") } } 242
  152. inline fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element

    in this) { loop(element) } } fun inlined(elements: List<Int>) { elements.forEach { println("Inlined: $it") } } 243
  153. inline fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element

    in this) { loop(element) } } fun inlined(elements: List<Int>) { elements.forEach { println("Inlined: $it") } } 244
  154. public static void forEach(List $receiver, Function1 loop) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver");

    Intrinsics.checkParameterIsNotNull(loop, "loop"); Iterator var3 = $receiver.iterator(); while(var3.hasNext()) { Object element = var3.next(); loop.invoke(element); } } 245
  155. inline fun <T> List<T>.forEach(loop: (T) -> Unit) { for (element

    in this) { loop(element) } } fun inlined(elements: List<Int>) { elements.forEach { println("Inlined: $it") } } 246
  156. public static void inlined(List elements) { Iterable iterable = (Iterable)elements;

    Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } } 247
  157. public static void inlined(List elements) { Iterable iterable = (Iterable)elements;

    Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } } 248
  158. public static void inlined(List elements) { Iterable iterable = (Iterable)elements;

    Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } } 249
  159. public static void inlined(List elements) { Iterable iterable = (Iterable)elements;

    Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } } 250
  160. public static void inlined(List elements) { Iterable iterable = (Iterable)elements;

    Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } } 251
  161. 252

  162. Iterable iterable = (Iterable)elements; Iterator var3 = iterable.iterator(); while(var3.hasNext()) {

    Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } 254
  163. Iterable iterable = (Iterable)elements; Iterator var3 = iterable.iterator(); while(var3.hasNext()) {

    Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } Iterable iterable = (Iterable)elements; Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } Iterable iterable = (Iterable)elements; Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } Iterable iterable = (Iterable)elements; Iterator var3 = iterable.iterator(); while(var3.hasNext()) { Object element = var3.next(); int it = ((Number)element).intValue(); String var7 = "Inlined: " + it; System.out.println(var7); } 255
  164. 257

  165. 259

  166. fun main(nullableString: String?) { val builder = StringBuilder() builder.append("a") builder.append("b")

    builder.append("c") nullableString?.let { builder.append(it) } } 262
  167. fun main(nullableString: String?) { val builder = StringBuilder() builder.append("a") builder.append("b")

    builder.append("c") nullableString?.let { builder.append(it) } } 263
  168. fun main(nullableString: String?) { val builder = StringBuilder() builder.append("a") builder.append("b")

    builder.append("c") nullableString?.let { builder.append(it) } } 264
  169. fun main(nullableString: String?) { val builder = StringBuilder() builder.append("a") builder.append("b")

    builder.append("c") nullableString?.let { builder.append(it) } } 265
  170. 267

  171. fun main() { val builder = StringBuilder() with(builder) { append("a")

    append("b") append("c") // StringBuilder } // returns last value provided// StringBuilder } 270
  172. fun main() { val builder = StringBuilder() builder.apply { append("a")

    append("b") append("c") "c" // last provided value is String } // returns receiver // StringBuilder } 273
  173. 274

  174. 275

  175. class BankAccount { var accountNumber: Long var owner: String var

    balance: Double } val bankAccount = BankAccount() bankAccount.accountNumber = 123L bankAccount.owner = "Bart" bankAccount.balance = 100.00 277
  176. class BankAccount { var accountNumber: Long var owner: String var

    balance: Double var branch: String var interestRate: Double } val bankAccount = BankAccount() bankAccount.accountNumber = 123L bankAccount.owner = "Bart" 278
  177. public static class Builder { private long accountNumber; //This is

    important, so we'll pass it to the constructor. private String owner; private String branch; private double balance; private double interestRate; public Builder(long accountNumber) { this.accountNumber = accountNumber; } public Builder withOwner(String owner){ this.owner = owner; return this; //By returning the builder each time, we can create a fluent interface. } public Builder atBranch(String branch){ this.branch = branch; return this; } public Builder openingBalance(double balance){ this.balance = balance; return this; } public Builder atRate(double interestRate){ this.interestRate = interestRate; return this; } public BankAccount build(){ //Here we create the actual bank account object, which is always in a fully initialised state when it's returned. BankAccount account = new BankAccount(); //Since the builder is in the BankAccount class, we can invoke its private constructor. account.accountNumber = this.accountNumber; 279
  178. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch = "Tel-Aviv" interestRate = 2.5 } 299
  179. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch = "Tel-Aviv" interestRate = 2.5 } 300
  180. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch = "Tel-Aviv" interestRate = 2.5 } 301
  181. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch = Branch() interestRate = 2.5 } 302
  182. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch = Branch() interestRate = 2.5 } 306
  183. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch { } interestRate = 2.5 } 307
  184. bankAccount { accountNumber = 123L owner = "Bart" balance =

    100.00 branch { city = "Tel Aviv" administrator = "Hadas Peled" services = listOf("deposits") } interestRate = 2.5 } 308
  185. 309

  186. 311

  187. 312

  188. 313

  189. 314

  190. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA 318
  191. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } 319
  192. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } 320
  193. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } 321
  194. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } 322
  195. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } 323
  196. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } 324
  197. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } 325
  198. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } runNow(runnable) 326
  199. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } val runnable = object: Runnable { override fun run() { println("I am runnable") } } runNow(runnable) 327
  200. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } 328
  201. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } runNow(Runnable{println("I am runnable")}) 329
  202. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } runNow(Runnable{println("I am runnable")}) 330
  203. • Interface with one abstract method public interface Runnable {

    //JAVA public abstract void run(); //JAVA } //JAVA fun runNow(runnable: Runnable) { runnable.run() } runNow(Runnable{println("I am runnable")}) 331
  204. 332

  205. 333

  206. // Kotlin class MyClass{ var text = "Hello world" }

    Kotlin Decompiler - Android studio 1. Menu > Tools > Kotlin > Show Kotlin Bytecode 2. Click on the Decompile button 3. Copy the java code 337
  207. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 338
  208. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 339
  209. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 340
  210. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 341
  211. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 342
  212. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 343
  213. // Kotlin class MyClass{ val text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private final String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 344
  214. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 345
  215. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 346
  216. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 347
  217. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 348
  218. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 349
  219. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 350
  220. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 351
  221. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 352
  222. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 353
  223. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 354
  224. // Kotlin class MyClass{ var text = "Hello world" }

    // Java - Decompiler public final class MyClass { @NotNull private String text = "Hello world"; @NotNull public final String getText() { return this.text; } public final void setText(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.text = var1; } } 355
  225. 356

  226. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 361
  227. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 362
  228. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 363
  229. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 364
  230. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 365
  231. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 366
  232. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 367
  233. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - Decompiler public final class AppKt { public static final void getTime() { } } public final class Util { } 368
  234. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file 369
  235. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file 370
  236. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file new org.example.Util(); 371
  237. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file new org.example.Util(); 372
  238. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.AppKt.getTime(); 373
  239. // Kotlin file - app.kt package org.example class Util fun

    getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.AppKt.getTime(); 374
  240. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.AppKt.getTime(); 375
  241. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.AppKt.getTime(); 376
  242. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.AppKt.getTime(); 377
  243. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); 378
  244. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); 379
  245. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); // Kotlin file - apps.kt package org.example fun getDate() { /*...*/ } 380
  246. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); // Kotlin file - apps.kt package org.example fun getDate() { /*...*/ } 381
  247. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); // Kotlin file - apps.kt package org.example fun getDate() { /*...*/ } 382
  248. // Kotlin file - app.kt @file:JvmName("Utils") package org.example class Util

    fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); // Kotlin file - apps.kt @file:JvmName("Utils") package org.example fun getDate() { /*...*/ } 383
  249. // Kotlin file - app.kt @file:JvmName("Utils") @file:JvmMultifileClass package org.example class

    Util fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); // Kotlin file - apps.kt @file:JvmName("Utils") @file:JvmMultifileClass package org.example fun getDate() { /*...*/ } 384
  250. // Kotlin file - app.kt @file:JvmName("Utils") @file:JvmMultifileClass package org.example class

    Util fun getTime() { /*...*/ } // Java - My file new org.example.Util(); org.example.Utils.getTime(); org.example.Utils.getDate(); // Kotlin file - apps.kt @file:JvmName("Utils") @file:JvmMultifileClass package org.example fun getDate() { /*...*/ } 385
  251. 386

  252. // Kotlin val flavor = "Vanilla" fun getFlavor(): String =

    "I taste like $flavor" // Platform declaration clash: // The following declarations have the same JVM signature. 389
  253. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 391
  254. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 392
  255. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 393
  256. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 394
  257. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 395
  258. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor(): String

    = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 396
  259. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor() :

    String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 397
  260. // Kotlin val flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor() :

    String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 398
  261. // Kotlin var flavor = "Vanilla" @JvmName("getFlavorFormat") fun getFlavor() :

    String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 399
  262. // Kotlin @get:JvmName("flavor") @set:JvmName("changeFlavor") var flavor = "Vanilla" @JvmName("getFlavorFormat") fun

    getFlavor() : String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 400
  263. // Kotlin @get:JvmName("flavor") @set:JvmName("changeFlavor") var flavor = "Vanilla" @JvmName("getFlavorFormat") fun

    getFlavor() : String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 401
  264. // Kotlin @get:JvmName("flavor") @set:JvmName("changeFlavor") var flavor = "Vanilla" @JvmName("getFlavorFormat") fun

    getFlavor() : String = "I taste like $flavor" var isVanilla: Boolean @JvmName("getIsVanilla") get() = this.flavor == "Vanilla" @JvmName("setIsVanilla") set(value) { if(value) flavor = "Vanilla" } 402
  265. // Kotlin @get:JvmName("flavor") @set:JvmName("changeFlavor") var flavor = "Vanilla" @JvmName("getFlavorFormat") fun

    getFlavor() : String = "I taste like $flavor" var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 403
  266. // Kotlin @get:JvmName("flavor") @set:JvmName("changeFlavor") var flavor = "Vanilla" @JvmName("getFlavorFormat") fun

    getFlavor() : String = "I taste like $flavor" @get:JvmName("getIsVanilla") @set:JvmName("setIsVanilla") var isVanilla: Boolean get() = this.flavor == "Vanilla" set(value) { if(value) flavor = "Vanilla" } 404
  267. 405

  268. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 406
  269. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 407
  270. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 408
  271. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 409
  272. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 410
  273. // Kotlin object Flavors { const val VANILLA: String =

    "Vanilla" } class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } 411
  274. // Kotlin object Flavors { } class IceCream(val flavor: String

    = DEFAULT_FLAVOR, val cone: Boolean = true) { companion object { } } 412
  275. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } 413
  276. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } 414
  277. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } 415
  278. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file 416
  279. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file Flavors.getVanillaFlavor(); // ??? 417
  280. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file Flavors.getVanillaFlavor(); // Cannot resolve method 418
  281. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file IceCream.getDefaultFlavor(); // Cannot resolve method 419
  282. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file Flavors.INSTANCE.getVanillaFlavor(); 420
  283. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file Flavors.INSTANCE.getVanillaFlavor(); // WORKS 421
  284. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file IceCream.Companion.getDefaultFlavor(); 422
  285. // Kotlin object Flavors { fun getVanillaFlavor() = "Vanilla" }

    class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file IceCream.Companion.getDefaultFlavor(); // WORKS 423
  286. // Kotlin object Flavors { @JvmStatic fun getVanillaFlavor() = "Vanilla"

    } class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } 425
  287. // Kotlin object Flavors { @JvmStatic fun getVanillaFlavor() = "Vanilla"

    } class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { @JvmStatic fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } 426
  288. // Kotlin object Flavors { @JvmStatic fun getVanillaFlavor() = "Vanilla"

    } class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { @JvmStatic fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file 427
  289. // Kotlin object Flavors { @JvmStatic fun getVanillaFlavor() = "Vanilla"

    } class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file Flavors.getVanillaFlavor(); // WORKS 428
  290. // Kotlin object Flavors { @JvmStatic fun getVanillaFlavor() = "Vanilla"

    } class IceCream(val flavor: String = getDefaultFlavor(), val cone: Boolean = true) { companion object { @JvmStatic fun getDefaultFlavor() = Flavors.getVanillaFlavor() } } // Java - My file IceCream.getDefaultFlavor(); // WORKS 429
  291. // Kotlin class IceCream(var flavor: String = "Vanilla", var cone:

    Boolean = true) { constructor(topping: String): this() { cone = false } } 430
  292. // Kotlin class IceCream(var flavor: String = "Vanilla", var cone:

    Boolean = true) { constructor(topping: String): this() { cone = false } } 431
  293. // Kotlin class IceCream(var flavor: String = "Vanilla", var cone:

    Boolean = true) { constructor(topping: String): this() { cone = false } } 432
  294. // Kotlin class IceCream(var flavor: String = "Vanilla", var cone:

    Boolean = true) { constructor(topping: String): this() { cone = false } } val vanillaCone = IceCream() val choclateCone = IceCream("Chocolate") val choclateCup = IceCream("Chocolate", false) val vanillaCup = IceCream(cone = false) val vanillaCupSprinkles = IceCream(topping = "Sprinkles") 433
  295. 434

  296. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla",var cone: Boolean = true) { constructor(topping: String): this() { cone = false } } 436
  297. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(topping: String): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() 437
  298. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(topping: String): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) // thanks JvmOverloads 438
  299. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(topping: String): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) 439
  300. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(topping: String): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) // thanks JvmOverloads IceCream(String topping) // secondary constructor 440
  301. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) 441
  302. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) 442
  303. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) 443
  304. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this() { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) 444
  305. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this("Vanilla", true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) 445
  306. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this("Vanilla", true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) 446
  307. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this("Vanilla", true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 447
  308. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this("Vanilla", true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 448
  309. 449

  310. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { constructor(balls: Int = 1): this("Vanilla", true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 450
  311. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { @JvmOverloads constructor(balls: Int = 1): this("Vanilla",true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 451
  312. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { @JvmOverloads constructor(balls: Int = 1): this("Vanilla",true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 452
  313. // Kotlin class IceCream @JvmOverloads constructor (var flavor: String =

    "Vanilla", var cone: Boolean = true) { @JvmOverloads constructor(balls: Int = 1): this("Vanilla",true) { cone = false } } // Java IceCream(String flavor, boolean cone) IceCream() IceCream(String flavor) IceCream(int balls) IceCream() 453
  314. 454

  315. Kotlin has three structural jump expressions: • return - By

    default returns from the nearest enclosing function or anonymous function. 456
  316. Kotlin has three structural jump expressions: • return - By

    default returns from the nearest enclosing function or anonymous function. • break - Terminates the nearest enclosing loop. 457
  317. Kotlin has three structural jump expressions: • return - By

    default returns from the nearest enclosing function or anonymous function. • break - Terminates the nearest enclosing loop. • continue - Proceeds to the next step of the nearest enclosing loop. 458
  318. 459

  319. loop@ for (i in 1..100) { innerLoop@ for (j in

    1..100) { if (...) break } } 462
  320. loop@ for (i in 1..100) { innerLoop@ for (j in

    1..100) { if (...) break } } 463
  321. loop@ for (i in 1..100) { innerLoop@ for (j in

    1..100) { if (...) break } } 464
  322. loop@ for (i in 1..100) { innerLoop@ for (j in

    1..100) { if (...) break@loop } } 465
  323. 466

  324. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return print(it) } print("this point is unreachable") } 467
  325. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return print(it) } print("this point is unreachable") } 468
  326. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return print(it) } print("this point is unreachable") } 469
  327. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return print(it) } print("this point is unreachable") } 470
  328. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return // return to the caller of foo() print(it) } print("this point is unreachable") } 471
  329. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return // return to the caller of foo() print(it) } print("this point is unreachable") } 472
  330. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return // return to the caller of foo() print(it) } print("this point is unreachable") } 473
  331. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return // return to the caller of foo() print(it) } print("this point is unreachable") } 12 474
  332. fun foo() { listOf(1, 2, 3, 4, 5).forEach gil@{ if

    (it == 3) return@gil print(it) } print(" done with explicit label") } 475
  333. fun foo() { listOf(1, 2, 3, 4, 5).forEach gil@{ if

    (it == 3) return@gil //return to the caller of lambda print(it) } print(" done with explicit label") } 476
  334. fun foo() { listOf(1, 2, 3, 4, 5).forEach gil@{ if

    (it == 3) return@gil //return to the caller of lambda print(it) } print(" done with explicit label") } 1245 done with explicit label 477
  335. fun foo() { listOf(1, 2, 3, 4, 5).forEach { if

    (it == 3) return@forEach//return to caller of lambda print(it) } print(" done with implicit label") } 1245 done with explicit label 478
  336. fun foo() { listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {

    if (value == 3) return print(value) }) print(" done with anonymous function") } 479
  337. fun foo() { listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {

    if (value == 3) return//return to caller of a.f print(value) }) print(" done with anonymous function") } 1245 done with explicit label 480
  338. 484

  339. 485

  340. 489

  341. 493

  342. fun isOdd(x: Int) = x % 2 != 0 val

    numbers = listOf(1, 2, 3) 496
  343. fun isOdd(x: Int) = x % 2 != 0 val

    numbers = listOf(1, 2, 3) println(numbers.filter(::isOdd)) 497
  344. fun isOdd(x: Int) = x % 2 != 0 val

    numbers = listOf(1, 2, 3) println(numbers.filter(::isOdd)) 498
  345. fun isOdd(x: Int) = x % 2 != 0 val

    numbers = listOf(1, 2, 3) println(numbers.filter(::isOdd)) Here ::isOdd is a value of function type (Int) -> Boolean 499
  346. 501

  347. 502

  348. //Operations val sum: (Int, Int) -> Int = { x,

    y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 503
  349. //Operations val sum: (Int, Int) -> Int = { x,

    y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 504
  350. //Operations val sum: (Int, Int) -> Int = { x,

    y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 505
  351. //Operations val sum: (Int, Int) -> Int = { x,

    y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 506
  352. typealias IntOperation = (Int, Int) -> Int //Operations val sum:

    (Int, Int) -> Int = { x, y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 507
  353. typealias IntOperation = (Int, Int) -> Int //Operations val sum:

    (Int, Int) -> Int = { x, y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 508
  354. typealias IntOperation = (Int, Int) -> Int //Operations val sum:

    (Int, Int) -> Int = { x, y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 509
  355. typealias IntOperation = (Int, Int) -> Int //Operations val sum:

    IntOperation = { x, y -> x + y } val sub: (Int, Int) -> Int = { x, y -> x - y } val multiply: (Int, Int) -> Int = { x, y -> x * y } Val diff: (Int, Int) -> Int = { x, y -> x / y } 510
  356. typealias IntOperation = (Int, Int) -> Int //Operations val sum:

    IntOperation = { x, y -> x + y } val sub: IntOperation = { x, y -> x - y } val multiply: IntOperation = { x, y -> x * y } Val diff: IntOperation = { x, y -> x / y } 511
  357. Collections typealias CoolKey = String typealias CoolValue = String val

    regularMap = mapOf<String, String>() val muchMoreReadableMap = mapOf<CoolKey, CoolValue>() 513
  358. Collections typealias CoolKey = String typealias CoolValue = String val

    regularMap = mapOf<String, String>() val muchMoreReadableMap = mapOf<CoolKey, CoolValue>() 514
  359. Collections typealias CoolKey = String typealias CoolValue = String val

    regularMap = mapOf<String, String>() val muchMoreReadableMap = mapOf<CoolKey, CoolValue>() 515
  360. Collections typealias CoolKey = String typealias CoolValue = String val

    regularMap = mapOf<String, String>() val muchMoreReadableMap = mapOf<CoolKey, CoolValue>() 516
  361. Classes class A { inner class Inner } class B

    { inner class Inner } typealias AInner = A.Inner typealias BInner = B.Inner 517
  362. Classes class A { inner class Inner } class B

    { inner class Inner } typealias AInner = A.Inner typealias BInner = B.Inner 518
  363. Classes class A { inner class Inner } class B

    { inner class Inner } typealias AInner = A.Inner typealias BInner = B.Inner 519
  364. Type aliases do not create new types. They simply give

    another name to an existing type. 520
  365. • Kotlin is a cool new language. • We have

    learn many things, how to make the code more readable, efficient and cleaner. • Keep learning Kotlin its only the tip of the iceberg… 529
  366. 530

  367. 532