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

The Kotlin & Java Blend

The Kotlin & Java Blend

Bob Dahlberg

June 15, 2017
Tweet

More Decks by Bob Dahlberg

Other Decks in Programming

Transcript

  1. Bob Dahlberg Isotop - Tech Lead Mobile
 Challenge Accepted -

    Founder Who’s Bob?
 - Building software
 - CrossFit Instructor
 - Soon to be father
 - Loves a good challenge!
  2. Background Scala & Functional Fell in love with functional programming

    and Scala 6 years ago.. .. and tried to write Android Apps with it.. 

  3. Background Scala & Functional Fell in love with functional programming

    and Scala 6 years ago.. .. and tried to write Android Apps with it.. ..it works!

  4. Background Scala & Functional Fell in love with functional programming

    and Scala 6 years ago.. .. and tried to write Android Apps with it.. ..it works!
 But it ain’t pretty.
  5. Background Scala & Functional Kotlin Works seamlessly It works! And

    it’s almost like it’s ment to be there!
  6. Background Scala & Functional Kotlin Works seamlessly In production February

    2016 Started mixing in kotlin classes in a feature branch late 2015. In February 2016 we went live with Kotlin classes.
  7. Blending Don’t be to eager to update and have the

    latest version of everything. They all have to sync. Only minor hiccups around version updates:
 - JDK - Kotlin - Android Support libs - Gradle - 3rd Party - Annotations
  8. Official Android Language Android Studio 3.0 (canary 3) available since

    early June. Will all hiccups magically disappear? Plausible! It will at least be fewer problems with syncing since Android Studio will bundle everything in a controlled manner.
  9. Official Android Language Android Studio 3.0 (canary 3) available since

    early June. Will all hiccups magically disappear? Plausible! It will at least be fewer problems with syncing since Android Studio will bundle everything in a controlled manner. Unless you use the early 
 access builds… ;)
  10. Alternatives Java 8 Jack and api <= 23 Android 7

    (api 24)
 has some Java 8 support “To test lambda expressions, method references, and type annotations on earlier versions of Android, go to your build.gradle file, and set compileSdkVersion and targetSdkVersion to 23 or lower. You will still need to enable the Jack toolchain to use these Java 8 features.”
  11. Alternatives Java 8
 Jack and api <= 23 Retrolambda Absolutely

    - but kotlin is so much more than lambdas and method reference.
  12. The Good Nullable var name:String? = “Bob” // name can

    be null 
 var family:String = “Dahlberg” // family can never be null
  13. The Good Nullable & Null safety fun release( dbs:List<Closeable?> )

    { dbs.forEach { it?.close() }
 } release( listOf( db1, null, db2 ) )
  14. The Good Nullable & Null safety var tmp:File? = null

    /* lots of code later */ tmp?.let{ file -> prinln( “Removing ${file.name}” ) file.delete() }

  15. The Good Nullable & Null safety Named params hide( true

    ) fun hide( animate:Boolean ) { // Implement…
 }
  16. The Good Nullable & Null safety Named params hide( animate

    = true ) fun hide( animate:Boolean ) { // Implement…
 }
  17. The Good Nullable & Null safety Named params Type Alias

    typealias Ref = KClass<out Any> typealias AliasMap = MutableMap<Int,Ref> val aliases:AliasMap fun find( alias:Int ):Ref? { return aliases[alias] }
  18. The Good Nullable & Null safety Named params Type Alias

    typealias Predicate<T> = (T) -> Boolean val even:Predicate<Int> = { it % 2 == 0 } listOf( 1, 2, 3 ).filter( even )
  19. The Good Nullable & Null safety Named params Type Alias

    When & With when( x ) { is Int -> println( "X is int" ) is String -> println( "X is String" ) else -> println( "Can't find x..." ) } when { month >= 4 -> println( "jan-apr" ) month in 5..8 -> println( "may-aug" ) month <= 9 -> println( "sep-dec" ) }
  20. The Good Nullable & Null safety Named params Type Alias

    When & With with( textView ) { setAllCaps( true ) setLines( 3 ) hint = "Add text" }
  21. The Good Nullable & Null safety Named params Type Alias

    When & With Modern list handling
 listOf( 1, 2, 3, 4, 5 ) .filter { it > 3 } .map { it * 2 } .first()
  22. The Good Nullable & Null safety Named params Type Alias

    When & With Modern list handling
 Extension Functions fun Int.squared() { 
 this * this } val Int.half get() = this / 2 3.squared() // 9 4.half // 2
  23. The Bad Calling not null params from Java // kotlin

    class Kotlin { fun send( message:String ){ // message is not nullable so we // don’t handle nulls } } // java public class Java { private String name; public Java( Kotlin instance ) { // No compile error instance.send( name ); } }
  24. The Bad Calling not null params from Java Extensions in

    data binding If a view uses google data binding, and the view model has extension functions. Those extension functions can’t be called.. yet?
  25. The Bad Calling not null params from Java Extensions in

    data binding Refactoring (getting better) When refactoring kotlin code via Studio that is referenced from Java doesn’t always work as expected.
  26. The Bad Calling not null params from Java Extensions in

    data binding Refactoring (getting better) Quote “It’s not as fun to write code in Java when you get used to the functionality from Kotlin.”
  27. The Ugly Object call from java object App { val

    version = “2.1” } // java App.INSTANCE.getVersion()
  28. The Ugly Object call from java class MyActivity { companion

    object { val TAG = “MyActivity” } } // java MyActivity.Companion.getTAG()
  29. The Ugly Object call from java class MyActivity { companion

    object { @JvmField val TAG = “MyActivity” } } // java MyActivity.TAG
  30. The Ugly Object call from java Extensions from Java //

    In file Extensions.kt fun Int.squared() { 
 this * this } // java ExtensionsKt.squared( 4 );
  31. The Ugly Object call from java Extensions from Java //

    In file Extensions.kt @file:JvmName(“Ext”) fun Int.squared() { 
 this * this } // java Ext.squared( 4 );
  32. The Ugly Object call from java Extensions from Java !!

    // They are there to be ugly… fun forceReplace( name:String? ):String { return name!!.replace( “_", “ " ) }
  33. The Ugly Object call from java Extensions from Java !!

    Auto-convert It’s getting a lot better but not good. You’ve got the foundation but then you should really refactor it. - Don’t make data classes for you - A lot of !! and ? to reflect the java code but often you can alter that - Copy paste from one language into the other usually works from Java to Kotlin but not the other way around.
  34. The Ugly Object call from java Extensions from Java !!

    Auto-convert Anonymous functions val listener = object:OnClickListener{
 override fun onClick( v:View? ) { // Implement…
 }
 }
  35. The Ugly Object call from java Extensions from Java !!

    Auto-convert Anonymous functions val listener = { view -> // implement
 }
  36. The Awesome Smart cast override fun onClick( v:View? ) {

    if( v != null ) { v.visibility = View.GONE // No question mark needed }
 }
  37. The Awesome Smart cast val hasValue = when( expr )

    {
 is String -> expr.isNotEmpty()
 is Int -> expr > 0 is IntArray -> expr.sum() > 0 else -> false
 }
  38. The Awesome Smart cast fun send( msg:String? ) {
 if(

    msg != null && msg.isNotBlank() ) { // do send it }
 }
  39. The Awesome Smart cast Delegates interface Engine { fun gas()

    fun brake() } class Turbo(val topSpeed:Int):Engine { var speed = 0 private set override fun gas() { speed = topSpeed } override fun brake() { speed = 0 } } class Car( e:Engine ):Engine by e val turboCar = Car( Turbo( 300 ) ) turboCar.gas()
  40. The Awesome Smart cast Delegates class Presenter() { val name

    by lazy { findViewById( R.id.name as TextView ) } }
  41. The Awesome Smart cast Delegates Data Classes data class Person(

    val name:String, val age:Int ) val bob = Person( “Bob”, 33 ) val youngBob = bob.copy( age = 15 ) print( bob ) // Person(name=Bob, age=33)
  42. The Awesome Smart cast Delegates Data Classes Deconstructing data class

    Person( val name:String, val age:Int ) val bob = Person( “Bob”, 33 ) // Deconstructing val (name,age) = bob
  43. The Awesome Smart cast Delegates Data Classes Deconstructing typealias Point

    = Pair<Int,Int> fun find():Point { // do some calculations return Point( 9, 6 ) } val (x,_) = find()
  44. The Awesome Smart cast Delegates Data Classes Deconstructing Operator overloading

    data class Person( val name:String, val age:Int ) val bob = Person( “Bob”, 33 ) operator fun Person.plus( inc:Int ) = copy( age = age + inc ) operator fun Person.plus( n:String ) = copy( name = “$name $n” ) bob + 2 // Person(name=Bob, age=35) bob + “D” // Person(name=Bob D, age=33)
  45. The Awesome Smart cast Delegates Data Classes Deconstructing Operator overloading

    a + b // a.plus(b) a - b // a.minus(b) a % b // a.rem(b) a..b // a.rangeTo(b) a += b // a.plusAssign(b) a in b // b.contains(a) a !in b // !b.contains(a) a > b // a.compareTo(b) > 0 a == b // a?.equals(b) ?: (b === null) a() // a.invoke()
  46. The Awesome Smart cast Delegates Data Classes Deconstructing Operator overloading

    And lots more… infix, default values, lambdas, type inference, method reference, inline functions, objects, interface functions, companion objects, interface properties, ranges, _, getters and setters…
  47. Bob Dahlberg @mr_bob - twitter @dahlberg.bob - medium.com bobdahlberg -

    speakersdeck.com Thanks! speakerdeck.com/bobdahlberg/the-kotlin-and-java-blend