From Java to Kotlin - Nullable Types & Null Checks

Nullable

In Kotlin variables cannot be null by default. This prevents many possible exceptions.

// function, with a non-nullable parameter
fun strLen(s: String) = s.length

// function, with a nullable parameter
fun strLen(s: String?) = s.length

Once you have a value of a nullable type, the set of operations you can perform on it are restricted.

  • You can no longer call methods on it.
  • You can’t assign it to a variable of a non-null type.
  • You can’t pass it as a parameter to a function expecting a non-null argument.

To solve this, you need to compare it with null. After this, the compiler remembers that and treats the value as being non-nullable.

Checking for null types

How to deal with nullable values

Safe Call Operator (?)

It checks a variable. If it isn’t null, the method is called normally. If it’s null, the call is skipped and null is used as the value.

// ? operator
s?.toUpperCase()

// this is the same as
if (s != null) {
  s.toUpperCase();
} else null;

Safe calls can be used for accessing properties as well, not just for method calls.

// create a class called employee with two properties
//    Employee may be null
class Employee(val name: String, val manager: Employee?)  

// function that takes an employee an takes the manager
//    name which returns a String that may be null
fun managerName(employee: Employee): String?
  = employee.manager?.name
Elvis Operator (?:)

It provides default values if a value is null

val nullableName: String? = ...
val name: String = nullableName ?: "default_name"

It’s often used together with the safe-call operator to substitute a value other than null when the object on which the method is called is null.

val nullableAddress: Address? = null
val postcode: String = nullableAddress?.postcode ?: "default_postcode"
Safe Cast (as?)

as tries to cast a value and throws ClassCastException if it cannot be converted
as? tries to cast a value but just returns null if it fails

// this would throw an exception because it's not a file
val path: Any = "/home/users"
val file: File? = any as File

// to avoid ClassCastException and have a null value if the cast fails
val safeInt: Int? = localtion as? Int
Not Null Assertions (!!)

Is the simplest way for dealing with a null value. It will convert any value to a non-null type. It forces the compiler to treat a value as a non-nullable.

You only want to use this if you know that the value is not null.

val nullableName: String? = "george"
val name: String = nullableName!!

If the value is null Kotlin will throw an exception at runtime.