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

Kotlin Types: Exposed

Svetlana Isakova
November 03, 2017
450

Kotlin Types: Exposed

Svetlana Isakova

November 03, 2017
Tweet

Transcript

  1. public static final int foo() { return 1; } @Nullable

    public static final Integer bar() { return Integer.valueOf(1); } Decompiled Java code
  2. fun foo(): Int = 1 public static final int foo()

    { return 1; } Correspondence between Kotlin and Java types Kotlin code: Decompiled Java code:
  3. public static final Integer foo() { return 1; } Correspondence

    between Kotlin and Java types Kotlin code: Decompiled Java code: fun bar(): Int? = 1
  4. Primitive & wrapper types Kotlin Java Int int Double double

    Boolean boolean Kotlin Java Int? java.lang.Integer Double? java.lang.Double Boolean? java.lang.Boolean
  5. No boxing now log(2017) fun log(any: Any) { println("Value: $any")

    } fun log(i: Int) { println("Value: $i") }
  6. Unit instead of void No meaningful value is returned fun

    f(): Unit { /*...*/ } Two equivalent syntactic forms: fun f() { /*...*/ }
  7. Nothing is different to Unit/void fun fail(message: String): Nothing {


    throw IllegalStateException(message)
 } It means “this function never returns”
  8. “a type that allows only one value and thus can

    hold no information” Unit Nothing “a type that has no values” “the function completes successfully” “the function never completes”
  9. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String) {
 throw IllegalStateException(message)
 } Let’s say, fail function returns Unit Int Unit Any : Unit
  10. val answer: Any = if (timeHasPassed()) { 42 } else

    { fail("Not ready") } fun fail(message: String) {
 throw IllegalStateException(message)
 } Int Any Unit Let’s say, fail function returns Unit
  11. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Now, fail returns Nothing
  12. val answer = if (timeHasPassed()) { 42 } else {

    fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Int Nothing Now, fail returns Nothing
  13. val answer: Int = if (timeHasPassed()) { 42 } else

    { fail("Not ready") } fun fail(message: String): Nothing {
 throw IllegalStateException(message)
 } Nothing Int Now, fail returns Nothing
  14. Type of null var user = null user = User("svtk")

    val users = mutableListOf(null) users.add(User("svtk")) Error: Type mismatch: inferred type is User but Nothing? was expected Error: Type mismatch: inferred type is User but Nothing? was expected
  15. Type of null var user: Nothing? = null user =

    User("svtk") val users: List<Nothing?> = mutableListOf(null) users.add(User("svtk"))
  16. Specify types explicitly var user: User? = null user =

    User("svtk") val users: List<User?> = mutableListOf(null) users.add(User("svtk")) ✓ ✓
  17. Type? then the code looks like Type And it doesn’t

    really work with generics !! !! !! !! !! !! !! !! !! !! !! !! If
  18. Platform type in error message public class Session {
 public

    String getDescription()
 } val session = Session()
 val description: Boolean = session.description Compiler error: Type mismatch: inferred type is String! but Boolean was expected
  19. Using Java from Kotlin val session = Session()
 val description

    = session.description
 println(description.length) NullPointerException! public class Session {
 public String getDescription() {
 return null;
 }
 }
  20. Different annotations are supported @Nullable @NotNull JetBrains @Nullable @NonNull Android

    @Nullable @CheckForNull JSR-305 @Nullable @CheckForNull FindBugs @NonNull Lombok ...
  21. Using Java from Kotlin public class Session { @Nullable String

    getDescription() { return null; } } val session = Session() val description = session.description println(description.length) compiler error
  22. Type @NotNull @Nullable Type Annotate your Java types - You

    can specify @NotNull as default, and annotate only @Nullable types - All of them???
  23. @MyNonnullByDefault public class Session { public void setDescription(String description) {

    this.description = description; } } @NonNull by default val session = Session() session.setDescription(null) Warning: Expected type doesn’t accept nulls in Java, but the value may be null in Kotlin
  24. @MyNonnullByDefault public class Session { public void setDescription(String description) {

    this.description = description; } } @NonNull by default val session = Session() session.setDescription(null) Error: Null can not be a value of a non-null type String
  25. Specify types explicitly val session = Session() val description: String?

    = session.description println(description?.length) public class Session {
 public String getDescription() {
 return null;
 }
 } ✓
  26. IllegalStateException: session.description must not be null val session = Session()

    val description: String = session.description public class Session {
 public String getDescription() {
 return null;
 }
 } Specify types explicitly
  27. val session = Session() val description: String = session.description println(description)

    Intrinsic checks is generated by the compiler throws an exception if session.description is null Intrinsics.checkExpressionValueIsNotNull( description, "session.description");
  28. Read-only immutable (1, 2, 3) • Read-only interface just lacks

    mutating methods • The actual list can be changed by another reference list mutableList
  29. val mutableList = mutableListOf(1, 2, 3) val list: List<Int> =

    mutableList println(list) // [1, 2, 3] (1, 2, 3) list mutableList (1, 2, 3, 4) mutableList.add(4) println(list) // [1, 2, 3, 4] Read-only immutable
  30. Under the hood fun getNames(): List<String>
 fun getNames(): MutableList<String> 


    java.util.List<String> getNames(); Both functions are compiled to:
  31. Platform type for Java collection collection type of “unknown” mutability

    List<String> (Mutable)List<String!> notation, not syntax type that came from Java
  32. Read-only interfaces improve API object Shop { private val customers

    = mutableListOf<Customer>() fun getCustomers(): List<Customer> = customers } val customers = Shop.getCustomers() customers.add() you can’t shoot yourself in the foot any longer
  33. Summary fun myFail(): Nothing = throw MyException() Preventing NPE: •

    annotations • explicit types @Nullable @MyNonnullByDefault Read-only immutable Nothing primitives under the hood boxing: Int Any