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

Effective Kotlin

Effective Kotlin

A lightning talk about how Kotlin helps you to write effective code based on Effective Java by Joshua Block.

Marcello Galhardo

April 17, 2019
Tweet

More Decks by Marcello Galhardo

Other Decks in Programming

Transcript

  1. // Kotlin object Singleton // Java public class Singleton {

    private Singleton INSTANCE; private Singleton() { } public Singleton getInstance() { if (INSTANCE != null) { INSTANCE = new Singleton(); } return INSTANCE; } }
  2. public class Api { public List<Object> doSearch( String deviceToken //

    other parameters ) { String customerId = getCustomerIdFromSessionToken(deviceToken); // Do something and returns the search return ArrayList(); } private String getCustomerIdFromSessionToken(String authToken) { // Retrieve the customer through the user session return "CustomerId"; } }
  3. public class Api { public List<Object> doSearch( String deviceToken //

    other parameters ) { String customerId = getCustomerIdFromSessionToken(deviceToken); // Do something and returns the search return ArrayList(); } private String getCustomerIdFromSessionToken(String authToken) { // Retrieve the customer through the user session return "CustomerId"; } }
  4. public class Api { public List<Object> doSearch( String deviceToken //

    other parameters ) { String customerId = getCustomerIdFromSessionToken(deviceToken); // Do something and returns the search return ArrayList(); } private String getCustomerIdFromSessionToken(String authToken) { // Retrieve the customer through the user session return "CustomerId"; } }
  5. public class Api { public List<Object> doSearch( String deviceToken //

    other parameters ) { String customerId = getCustomerIdFromSessionToken(deviceToken); // Do something and returns the search return ArrayList(); } private String getCustomerIdFromSessionToken(String authToken) { // Retrieve the customer through the user session return "CustomerId"; } }
  6. public class Api { public List<Object> doSearch( String deviceToken //

    other parameters ) { String customerId = getCustomerIdFromSessionToken(deviceToken); // Do something and returns the search return ArrayList(); } private String getCustomerIdFromSessionToken(String authToken) { // Retrieve the customer through the user session return "CustomerId"; } }
  7. class Api { fun doSearch( deviceToken: String // other parameters

    ): List<Any> { val customerId = getCustomerIdFromSessionToken(deviceToken) // Do something and returns the search return ArrayList() } private fun getCustomerIdFromSessionToken(authToken: String): String { // Retrieve the customer through the user session return "CustomerId" } }
  8. class Api { fun doSearch( deviceToken: String // other parameters

    ): List<Any> { val customerId = getCustomerIdFromSessionToken(deviceToken) // Do something and returns the search return ArrayList() } private fun getCustomerIdFromSessionToken(authToken: String): String { // Retrieve the customer through the user session return "CustomerId" } }
  9. class Api { fun doSearch( sessionToken: String // other parameters

    ): List<Any> { val customerId = getCustomerIdFromSessionToken(sessionToken) // Do something and returns the search return ArrayList() } private fun getCustomerIdFromSessionToken(sessionToken: String): String { // Retrieve the customer through the user session return "CustomerId" } }
  10. class Api { fun doSearch( sessionToken: SessionToken // other parameters

    ): List<Any> { val customerId = getCustomerIdFromSessionToken(sessionToken) // Do something and returns the search return ArrayList() } private fun getCustomerIdFromSessionToken(sessionToken: SessionToken): String { // Retrieve the customer through the user session return "CustomerId" } }
  11. // Kotlin class Foo open class Foo // Java public

    final class Foo {} public class Foo {}
  12. public interface Collection<E> : Iterable<E> { public val size: Int

    public fun isEmpty(): Boolean public fun contains(element: E): Boolean public fun containsAll(elements: Collection<E>): Boolean }
  13. sealed class ViewState { object Started: ViewState() object EditMode: ViewState()

    object ViewMode: ViewState() } fun verifyState(state: ViewState) { when (state) { is ViewState.Started -> println("Started") is ViewState.EditMode -> println("EditMode") is ViewState.ViewMode -> println("ViewMode") } }
  14. sealed class ViewState { object Started: ViewState() object EditMode: ViewState()

    object ViewMode: ViewState() class Error(val message: String = "Unknown error"): ViewState() } fun verifyState(state: ViewState) { when (state) { is ViewState.Started -> println("Started") is ViewState.EditMode -> println("EditMode") is ViewState.ViewMode -> println("ViewMode") } }
  15. sealed class ViewState { object Started: ViewState() object EditMode: ViewState()

    object ViewMode: ViewState() class Error(val message: String = "Unknown error"): ViewState() } fun verifyState(state: ViewState) { when (state) { is ViewState.Started -> println("Started") is ViewState.EditMode -> println("EditMode") is ViewState.ViewMode -> println("ViewMode") } } when expressions guarantee that their branches exhaustively check the possible subclasses of a sealed class.
  16. 'when' expression on sealed classes is recommended to be exhaustive,

    add 'Error' branch or 'else' branch instead
  17. sealed class ViewState { object Started: ViewState() object EditMode: ViewState()

    object ViewMode: ViewState() class Error(val message: String = "Unknown error"): ViewState() } fun verifyState(state: ViewState) { when (state) { is ViewState.Started -> println("Started") is ViewState.EditMode -> println("EditMode") is ViewState.ViewMode -> println(“ViewMode") is ViewState.Error -> println(state.message) } }
  18. fun requireNotNull(any: Any?) { if (any == null) throw IllegalArgumentException()

    } fun foo(s: String?) { requireNotNull(s) s.length }
  19. Only safe (?.) or non-null asserted (!!.) calls are allowed

    on a nullable receiver of type String?
  20. fun requireNotNull(any: Any?) { contract { returns() implies (any !=

    null) } if (any == null) throw IllegalArgumentException() } fun foo(s: String?) { requireNotNull(s) s.length }