Java vs Kotlin

Java vs Kotlin

Introduction of Kotlin for Java developers with side by side comparison

A8b79d304b5184e5a5b0a109590f6683?s=128

Danny Preussler

August 22, 2019
Tweet

Transcript

  1. Java vs Kotlin Danny Preussler Kotlin everywhere

  2. about:me •Java developer since 2003 •Kotlin developer since 2016 •Google

    Developer Expert for Android and Kotlin •Introduced Kotlin at Groupon and Viacom
  3. None
  4. None
  5. Kotlin adoption •Languages developers want to learn in 2019 •

    https://research.hackerrank.com/ developer-skills/2019
  6. Kotlin adoption Okt 18, GitHub: 'Kotlin for Android now fastest-growing

    programming language' https://www.zdnet.com/article/microsofts-github-kotlin-for-android-no w-fastest-growing-programming-language/
  7. Kotlin adoption Stackoverflow trends of JVM languages. #kotlin is first

    with a strong growth during the last 2 years.
  8. Kotlin adoption • JVM Ecosystem Report 2018 (10k questionaires): What

    is the principal JVM language you use for your main applications? • Kotlin edges past Groovy and Scala in language usage on 2.42% https://snyk.io/blog/jvm-ecosystem-report-2018/
  9. Kotlin adoption •1.5M+ developers edited Kotlin code in 2018 •100M+

    lines of Kotlin code •96,000+ Kotlin GitHub repositories •Android — 1 in 4 apps (from top 1000) uses Kotlin •Server — х2 from 2017 https://www.jetbrains.com/annualreport/2018/community/
  10. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    The year: 2010 Java6 has been around the 4th year
  11. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    The year: 2010 Kotlin Development started internally
  12. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    July 2010 Swift Development started
  13. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    July 2011 Java 7
  14. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    July 2011 JetBrains unveiled Project Kotlin
  15. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    February 2012 JetBrains open sourced Kotlin
  16. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    March 2014 Java 8
  17. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    June 2014 WWDC application became the first publicly released Swift app
  18. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    September 2014 Swift 1.0
  19. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    Februar 2016 Kotlin 1.0
  20. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    Google I/O 2017 Official Kotlin support for Android
  21. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    September 2017 Java 9
  22. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    March 2018 Java 10
  23. 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

    Google I/O 2019 Kotlin becomes preferred language for Android
  24. Why Kotlin?

  25. Goals of Kotlin Modern language Faster compilation than Scala Smaller

    footprint than Scala Designed to work perfectly with Java (designed for 6+8)
  26. Why Kotlin? Null safe Functional aspects Strongly typed but type

    Inference Reduces boilerplate
  27. Kotlin is.. Strongly typed Dynamic typed Object orientated Functional kotlin

    java scala groovy clojure
  28. Makes developers happy Happiness

  29. Basics String someString; final String someConstantString;

  30. Basics

  31. Basics var someString: String val someConstantString: String

  32. The power of type inference Integer doSomething(String someString) { return

    someString.getLength(); }
  33. The power of type inference

  34. The power of type inference fun doSomething(someString: String): Int {

    return someString.length }
  35. The power of type inference fun doSomething(someString: String): Int =

    someString.length
  36. The power of type inference fun doSomething(someString: String) = someString.length

  37. Type inference in Java HashMap<String,Integer> x = new HashMap<String,Integer>();

  38. Type inference in Java HashMap<String,Integer> x = new HashMap();

  39. Type inference in Java 10 var x = new HashMap<String,Integer>();

  40. Type inference in Java 10 Difference to Kotlin: • var

    is not a keyword in Java 10 • it‘s a reserved type name
  41. Let’s talk about null

  42. Lets talk null I call it my billion-dollar mistake. It

    was the invention of the null reference in 1965   Tony Hoare ( inventor of the null reference)
  43. Lets talk null if (button != null){ button.onPressed(); }

  44. Lets talk null if (button.isPresent()){ button.get().onPressed(); }

  45. Lets talk null

  46. Lets talk null button?.onPressed()

  47. Lets talk null someString?.length

  48. Lets talk null someString?.length ?: 0

  49. Lets talk null someString!!.length

  50. Lets talk null val someString : String? …

  51. Lets talk null •Equivalent in Java: @NonNull but runtime crash

    vs compiler only •Nullability is Part of Typesystem
  52. Lets talk null fun some(thing: String?) {…} public final void

    some( @Nullable String thing) {…}
  53. Lets talk null fun some(thing: String) {…} public final void

    some( @NotNull String thing) { checkParameterIsNotNull(thing, "thing"); }
  54. Smart casts Object someString … if (someString instanceOf String) {

    ((String)someString).getLength(); }
  55. Smart casts

  56. Smart casts val someString : Any if (someString is String)

    { someString.length }
  57. Getter, setter view.setVisibility(View.GONE);

  58. Getter, setter

  59. Getter, setter view.visibility = View.GONE

  60. Lambdas •Came in Java-8 •Android devs had to rely on

    Retrolambda very long
  61. Lambdas list.forEach( element -> System.out.println(element) );

  62. Lambdas

  63. Lambdas list.forEach{ element -> System.out.println(element) }

  64. Lambdas list.forEach{ System.out.println(it) }

  65. Collections List<String> myList = Arrays.asList("1", "2", "3")

  66. Collections

  67. Collections val myList = listOf("1", "2", "3") val myList =

    mutablelistOf("1", "2", "3")
  68. Streams tags.stream() .map(tag -> tag.replace("#", "")) .collect(joining(",");

  69. Streams

  70. Streams tags.map{ it.replace("#", "") } .join(",")

  71. Streams tags.asSequence(). .map{ it.replace("#", "") } .join(",")

  72. default parameters vs overloading class Api { Api(String baseURl) {

    this(baseURl, CacheStrategy.NO_CACHE) } Api(String baseURl, CacheStrategy cache) { } }
  73. default parameters vs overloading

  74. default parameters vs overloading class Api( baseUrl: String, cache: CacheStrategy

    = CacheStrategy.NO_CACHE )
  75. default parameters vs overloading class Api( private val baseUrl: String,

    val cache: CacheStrategy = CacheStrategy.NO_CACHE )
  76. Data classes data class Team( val name: String? = null,

    val logo: String? = null )
  77. Sealed classes sealed class LoadingState { class Loading : LoadingState()

    class Loaded : LoadingState() class Empty : LoadingState() }
  78. Lazy initialization public class LazyField { private String value; public

    String getValue() { if (value == null) { value = computeValue(); } return value } private String computeValue() { .... } }
  79. Lazy initialization

  80. Lazy initialization class LazyField { val: String by lazy {

    computeValue() } private fun computeValue()= … }
  81. Lazy initialization •Framework class like Activities: no control over constructor

    •How use the compiler to check for null?
  82. Late initialization •Framework class like Activities: no control over constructor

    •How use the compiler to check for null?
  83. Late initialization View someView; ... someView = findViewbyId(R.id.myView);

  84. Late initialization

  85. Late initialization lateinit someView: View ... someView = findViewbyId(R.id.myView);

  86. Primitives in Kotlin

  87. Primitives in Kotlin •No primitives

  88. Primitives in Kotlin •No primitives int a; Integer b; a:

    Int
  89. Primitives in Kotlin •No primitives •Boxing? Therefore no boxing issues

    (mostly) int a; Integer b; a: Int
  90. Primitives in Kotlin: Costs? •The numeric type usages in Kotlin

    are compiled into JVM primitives where possible. •Compiler decides
  91. Primitives in Kotlin: Costs? •The numeric type usages in Kotlin

    are compiled into JVM primitives where possible. •Compiler decides •Works because of missing widening int a = 1; double b = a; val a:Int = 1 val b:Double = a
  92. Primitives in Kotlin •Nullable type cannot be primitive •Primitives cannot

    be used as a generic type argument. •List<Int> is equivalent of Java List<Integer> •Therefore IntArray as type!
  93. Operator overloading

  94. Operator overloading operator fun plusAssign(callback: Callback) { callbacks.add(callback) } operator

    fun minusAssign(callback: Callback) { callbacks.remove(callback) } adapterCallbacks += {…}
  95. Expression Translated to a++ a.inc() + see below a-- a.dec()

    + see below Expression Translated to +a a.unaryPlus() -a a.unaryMinus() !a a.not() Expression Translated to a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b), a.mod(b) (deprecated) a..b a.rangeTo(b)
  96. Operator overloading Expression Translated to a > b a.compareTo(b) >

    0 a < b a.compareTo(b) < 0 a >= b a.compareTo(b) >= 0 a <= b a.compareTo(b) <= 0 Expression Translated to a == b a?.equals(b) ?: (b === null) a != b !(a?.equals(b) ?: (b === null))
  97. Operator overloading Expression Translated to a in b b.contains(a) a

    !in b !b.contains(a) Expression Translated to a[i] a.get(i) a[i, j] a.get(i, j) a[i_1, ..., i_n] a.get(i_1, ..., i_n) a[i] = b a.set(i, b) a[i, j] = b a.set(i, j, b) a[i_1, ..., i_n] = b a.set(i_1, ..., i_n, b)
  98. Operator overloading Expression Translated to a() a.invoke() a(i) a.invoke(i) a(i,

    j) a.invoke(i, j) a(i_1, ..., i_n) a.invoke(i_1, ..., i_n) Expression Translated to a += b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a /= b a.divAssign(b) a %= b a.remAssign(b), a.modAssign(b) (deprecated)
  99. Operator overloading •Range expression for (i in 1..4) print(i) operator

    fun rangeTo(other: Int) = IntRange(this, other)
  100. Operator overloading in RxKotlin disposables += clips.subscribeBy( onError = {

    logE(it) }, onNext = { onNewClip(it) } )
  101. Getter / Setter var live = true private set

  102. Getter / Setter val live get() = category.live val live

    = category.live
  103. Getter / Setter val live get() = category.live

  104. Getter / Setter val live get() = category.live public final

    boolean getLive() { return category.getLive(); }
  105. Delegated properties var something: Something by lazy{} var something: Something

    by inject{}
  106. Delegation •inheritance Effective Java: Item 16: Favor composition over inheritance

    class FirebaseFeatureFlags ( private val defaults: DefaultFeatureFlags ) : FeatureFlags by defaults {
  107. Singleton class Singleton { final static Singleton instance = new

    Singleton() private Singleton() {} }
  108. Singleton

  109. Singleton object Singleton

  110. Extension functions class Utils { public static boolean isNonNullOrEmpty(String string){

    … } } isNonNullOrEmpty(“hallo“)
  111. Extension functions

  112. Extension functions fun String?.isNonNullOrEmpty() = {…} “hallo“.isNonNullOrEmpty()

  113. Extension functions fun String?.isNonNullOrEmpty() = {…} public static final boolean

    isNonNullOrEmpty( @Nullable String $receiver) {… }
  114. Standard functions val calendar = Calendar.getInstance(Locale.US).apply { set(Calendar.DAY_OF_MONTH, 3) set(Calendar.MONTH,

    Calendar.MARCH) set(Calendar.YEAR, 1990) }
  115. Standard functions

  116. Infix val game = homeTeam.vs(guestTeam)

  117. Infix val game = homeTeam.vs(guestTeam) val game = homeTeam vs

    guestTeam
  118. Infix val game = homeTeam.vs(guestTeam) val game = homeTeam vs

    guestTeam infix fun Team.vs(team: Team) = Pairing(this, team)
  119. @Test void shouldMapComponentsToDomain()

  120. @Test void should_map_components_to_domain()

  121. None
  122. @Test void `should map components to domain`()

  123. inlining

  124. inline •Avoid runtime penalties of wrappers by inline”ing

  125. inline •Powerful with reified: Allows generics with type check: T::class

    inline fun <reified T : Context> Activity.start() { startActivity(Intent(this, T::class.java)) }
  126. inline inline fun <reified T : Context> Activity.start() { startActivity(Intent(this,

    T::class.java)) } start<MainActivity>() $receiver$iv.startActivity( new Intent( (Context)$receiver$iv, MainActivity.class) );
  127. inline •Inline classes •Experimental inline class Time(private val timeMs: Long)

  128. inline •Inline classes •Experimental •Inline classes are final •Can lead

    to weird boxing issues •Not compatible with @Parcelize inline class Time(private val timeMs: Long)
  129. Coroutines

  130. • Lightweight threads • Allows asynchronous code to be written

    sequentially suspend fun concurrentSum(): Int = coroutineScope { val one = async { doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } one.await() + two.await() }
  131. Some changes

  132. In/out https://twitter.com/fmuntenescu/status/982268265853476867

  133. Static? class Job { static String ERROR = null }

  134. Static? class Job { companion object { var ERROR: String

    = null } }
  135. Other changes •Classes/methods public by default

  136. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open)
  137. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner)
  138. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner) •Stricter usage of protected
  139. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner) •Stricter usage of protected •New visibility: internal
  140. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner) •Stricter usage of protected •New visibility: internal •One file can have multiple public classes
  141. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner) •Stricter usage of protected •New visibility: internal •One file can have multiple public classes •„global“ functions & variables are allowed
  142. Other changes •Classes/methods public by default •Classes/methods final by default

    (vs open) •Inner class: static by default (vs inner) •Stricter usage of protected •New visibility: internal •One file can have multiple public classes •„global“ functions & variables are allowed •No checked Exceptions
  143. Other changes •void -> Unit •Object -> Any

  144. Other changes •void -> Unit •Object -> Any •Plus Nothing

  145. Bad news something ? 1 : 0 something != null

    ? something : "" ☹
  146. Bad news if (something ) 1 else 0 ☹ something

    ?: ""
  147. Java Interop

  148. Java Interop public final class FileKt { public static final

    void foobar() {..} } //File.kt fun foobar(){..}
  149. Java Interop •@JvmOverloads •@JvmStatic •@JvmField •@JvmName •@Throws

  150. Java Interop •Careful with „sneaky“ Kotlin exceptions •@Throws

  151. Java Interop @Metadata( mv = {1, 1, 13}, bv =

    {1, 0, 3}, k = 1, d1 = {"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\ u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0002 \b\u0003\u0018\u00002\u00020\u0001:\u0001\u0006B\ u0005¢ \u0006\u0002\u0010\u0002J\b\u0010\u0003\u001a\u00 020\u0004H\u0007J\u0006\u0010\u0005\u001a\u00020\ u0004¨\u0006\u0007"}, d2 = {"Lde/jodamob/android/kotlin/T_TestingTest;", "", "()V", "test", "", "throwSomething", "Something", "app"} )
  152. Java Interop •Performance in most case same as Java https://de.slideshare.net/intelliyole/kotlin-bytecode-generation-and-runtime-performance

  153. Compile time

  154. Compile time

  155. Runtime • Execution time: difference [..] can vary from 6.7%

    in favor of Java [..], to 1.2% in favor of Kotlin [..] • Memory consumption: appeared the lowest in the Java implementation in four out of six benchmarks. • CPU load: no significant distinction in load management https://medium.com/@bards95/comparative-evaluation-of-selected-constru cts-in-java-and-kotlin-part-1-dynamic-metrics-2592820ce80
  156. Runtime • Execution time: difference [..] can vary from 6.7%

    in favor of Java [..], to 1.2% in favor of Kotlin [..] • Memory consumption: appeared the lowest in the Java implementation in four out of six benchmarks. • CPU load: no significant distinction in load management https://medium.com/@bards95/comparative-evaluation-of-selected-constru cts-in-java-and-kotlin-part-1-dynamic-metrics-2592820ce80
  157. Runtime • Execution time: difference [..] can vary from 6.7%

    in favor of Java [..], to 1.2% in favor of Kotlin [..] • Memory consumption: appeared the lowest in the Java implementation in four out of six benchmarks. • CPU load: no significant distinction in load management https://medium.com/@bards95/comparative-evaluation-of-selected-constru cts-in-java-and-kotlin-part-1-dynamic-metrics-2592820ce80
  158. Sum up

  159. Kotlin Less code

  160. Less Code Kotlin .. helps to increase a cut in

    the lines of code by approximately 40 % (JetBrains) … tests show … the number of code lines reduces by 30… https://belitsoft.com/apps-development-services/java-vs-kotlin
  161. Kotlin Less code No more null

  162. Kotlin Less code Easy to learn No more null

  163. Kotlin No revolution

  164. Kotlin No revolution Just evolution

  165. Kotlin No revolution (pragmatic) evolution

  166. Kotlin ‘Kotlin isn't revolutionary (with the possible exception of its

    null-handling) but feels like a very careful amalgamation of some of the best features of other languages. Rob Fletcher, Netflix https://belitsoft.com/apps-development-services/java-vs-kotlin
  167. Kotlin is … „Scala for Dummies” https://towardsdatascience.com/introduction-to-kotlin-statistics-cdad3be88b5

  168. Makes developers happy fun fun fun

  169. Get started

  170. Thank you @PreusslerBerlin