Skip to end of metadata
Go to start of metadata

Nullable types and Non-null types

One of the most common pitfalls in Java programming is accessing a member of a null reference, that results in a NullPointerException, because virtually any reference in a Java program can hold null. It happens so often that we have a casual abbreviation for it: NPE. Also have a look at this talk: "The Billion Dollar Mistake".

Kotlin's type system is aimed to eliminate NullPointerException's from our code. The only possible causes of NPE's may be

  1. Someone had explicitly thrown is (throw NullPointerException())
  2. Someone called external Java code that caused it
  3. There's data inconsistency w.r.t initialization (an uninitialized this available in a constructor is used somewhere)

In Kotlin the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can not hold null:

var a : String = "abc" 
a = 
null
 // compilation error

To allow nulls, one declares a variable as nullable string, written String?:

var b : String? = "abc" 
b = null // ok

Now, if you call a method on a, it's guaranteed not to cause an NPE, so you can safely say

val l = a.length()

But if you want to call the same method on b, that would not be safe, and the compiler reports an error:

val l = b
.
length() // error: variable 'b' can be null

But we still need to call that method, right? There are a few ways of doing that.

Checking for null in conditions

First, you can explicitly check if b is null, and handle the two options separately:

val l = if (b != null) b.length() else -1

The compiler tracks the information about the check you performed, and allows the call to length() inside the if. More complex conditions are supported as well:

if (b != null && b.length() > 0) 
  print("String of length ${b.length()}") 
else 
  print("Empty string")

Note that this only works where b is immutable (i.e. a local val or a member val which has a backing field and is not overridable), because otherwise it might happen that b changes to null after the check.

Safe calls

Your second option is the safe call operator, written ?.:

b?.length()

This returns b.length() if b is not null, and null otherwise. The type of this expression is Int?.

Safe calls are useful in chains. For example, if Bob, an Employee, may be assigned to a Department (or not), that in turn may have another Employee as a department head, then to obtain the name of Bob's department head, if any), we write the following:

bob?.department?.head?.name

Such a chain returns null if any of the properties in it is null.

Elvis operator

When we have a nullable reference r, we can say "if r is not null, use it, otherwise use some non-null value x":

val l : Int = if (b != null) b.length() else -1

Along with the complete if expression, this can be expressed with the Elvis operator, written ?::

val l = b?.length() ?: -1

If the expression to the left of ?: is not null, the elvis operator returns it, otherwise it returns the expression to the right. Note that the right-hand side expression is evaluated only if the left-hand side is null.

The !! operator

The third option is for NPE-lovers. One can write b!!, and this will return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:

val l = b!!.length()

Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the blue.

By the way, !! is added for conciseness, and formerly was emulated by an extension function from the standard library, defined as follows:

inline fun <T : Any> T?.sure() : T = 
  if (this == null) 
    throw NullPointerException() 
  else 
    this

Safe casts

Regular casts may result into a ClassCastException if the object is not of the target type. Another option is to use safe casts that return null is the attempt was not successful:

val aInt : Int? = a as? Int

Best practices related to this feature

J. Bloch, Effective Java. Second Edition
Item 38: Check parameters for validity
Item 43: Return empty arrays or collections, not nulls

Null Object Design Pattern
(Originally proposed by B. Woolf )

Similar features in other languages

In Java, one can use annotations on methods and parameters (or on types, when JSR-308 is accepted), these annotations can be used by external tools to verify null-safety. For example, one can use the @NotNull annotation supported by IntelliJ IDEA.

Scala promotes using the Option type to control absent values. This introduces run-time overhead because values are wrapped into objects of type Option, and the syntax is a little verbose.

C# has Nullable types that boil down to wrapping references into value types allocated on the stack, and there's no actual static checks that would prohibit calling methods on a null reference.

Groovy has Safe navigation and Elvis operators.

Gosu's approach is close to ours.

What's next

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 20, 2011

    Anonymous

    Any plans on adding Design By Contract type features other than null checking.  It is quite cumbersome in most languages to check for preconditions (postconditions, invariants) and then copy the precondition text into the function doc and then finally write a unit test to exercise the precondition check.

    For example:

    /** does it.
         @param i cannot be < 0 or > 100.
         @return will never be less than zero
    */
    int doIt(Int i) 

    Unknown macro: {if (i < 0 || i > 100) throw new IllegalArgumentException("i is invalid " + i);        ...}

    Instead I'd like to be able to write (maybe this isn't the best syntax but you get the idea). The conditions would be part of the method signature and therefore they don't have to be doc'd or tested (unless you want to make sure they don't change).

    /** does it. */ 
    int (< 0) doIt(int (< 0 || > 100) i) 

    Unknown macro: { ...}

    aside from reducing boilerplate docs, tests, etc. It would be cool if the compiler could check these constraints at compile time.  I'm thinking something similar to what microsoft is doing with specsharp & code contracts

    1. Jul 21, 2011

      We'll probably have it as a compiler plugin

  2. Jul 21, 2011

    Anonymous

    Typo: "ClassCastException is the object" should be "ClassCastException if the object"

    1. Jul 21, 2011

      Thanks, corrected

  3. Jul 21, 2011

    Anonymous

    How are static non-null class fields ensured when running code from inside field intializers? Does nonnull provide a hard constraint within the context of the ordering of initializers.

    Does this mean that fields that need to be initialized in the constructor can't be nonnull ?

    Any chance of a 'assign once' modifier for variables ?

    1. Jul 21, 2011

      We do the same level of assuredness of nonnullability as Java does for final fields being actually final. In some obscured initialization logic where reference to this is escaped before initialization is complete one may see final field being null even though it definitely initialized to some nonnull value.

  4. Jul 22, 2011

    Anonymous

    Looks very much like Nice which also assumes any Java code may return null unless you tell it otherwise by defining a more refined type signature for the import.

  5. Jul 23, 2011

    Anonymous

    How do you solve the null-safety with collections?

    Question 1:

    How do arrays get instantiated and initialized?

    A normal array with not nullable items:

    val a : Array<String> = Array<String>(5) // must not compile, because the items must not be null 
    val b : Array<Int> = Array<Int>(5) // must also not compile, but 'Int' may have the default value '0' 
     
    val c : Array<Int> = array("a", "b", "c", "d", "e") // is OK 
    val d : Array<Int> = array(1, 2, 3, 4, 5) // is OK

    An array which can contain null-references may look like this:

    val x : Array<Int?> = Array<Int?>(10) // is OK, because the items can be null 
     
    if(9 in x.indices) // check for length 
        x[9] = null // is OK

    Or a nulllable array which can contain null-references:

    val y : Array<Int?>? = Array<Int?>(10) 
     
    if(9 in y?.indices) // check for null and length 
    //       ^-- Would 'in' in combination with the safe call work? 
    //           What's with 'if(y?.length() > 9)' or 'if(y?length() > 9)'? 
    { 
        y[9] = null // is OK 
     
        // Get the value 
        val z : String = y[9]?.toString() ?: "<undefined>" 
    }

    If the items must not be null, how do you initialize an array in a loop?

    val a : Array<String> = Array<String>(5) // requires, that this is valid – even if 
                                             // the items are not nullable 
     
    // the compiler has to forbid access to the array until it's completely initialized 
     
    for(i in a.indices) 
        a[i] = "Item " + (i + 1) 
     
    // now, we can access the array 
    val item = a[0]

    Maybe one can specify a default value for initialization:

    val a : Array<String> = Array<String>(5, "<empty>") // initializes all items with "<empty>" 
     
    val item = a[0] // is valid, because it's initialized 
     
    // set custom values 
    for(i in a.indices) 
        a[i] = "Item " + (i + 1)

    Or a function for initialization:

    val a : Array<String> = Array<String>(5, index => "Item " + (index + 1))

    Or does there exist a special construct for initialization of collections?

    Question 2:

    What's with a generic dictionary? How does the developer of the dictionary specify, that the key must not be null? Or must null explicitly be allowed?

    class Dictionary<Key /* must not be null */, Value /* can be null */> ...
    Dictionary<String, String> // is OK 
    Dictionary<String, String?> // is OK 
    Dictionary<String?, String> // is invalid; must not compile 
    Dictionary<String?, String?> // is also invalid; must not compile

    Best regards,
    JMP

    1. Jul 26, 2011

      Your question one is a very good point. I would like to mention your name to give you credit for it. Please, feel free to contact me at andrey.breslav[]jetbrains.com.

      As of question two: if the generic dictionary class does not admit null keys at all, its declarations is:

      class Dictionary<K : Any, V> { ... }

      As the upperbound for K is Any, a nullable type cannot go there. The default upperbound (the one for V, for example) is Any?, and admits nullable types.

  6. Jul 24, 2011

    Anonymous

    Tipo: The link under "What's next" should probably be "Expressions", not "Exceptions".

    iu--

    1. Jul 26, 2011

      Fixed. Thanks

  7. Aug 04, 2011

    Anonymous

    Maybe add "?" as a postfix-operator also, so that you can write:

    instead of

    1. Aug 04, 2011

      This syntax is ambiguous:

      value?.foo()

      is it
      (value?).foo()

      or

      value ?. foo()

      ?

      1. Aug 04, 2011

        Anonymous

        Not if you define ?. and ? as separate tokens. And if you want to call a method on the result of x?, you have to use parens or a space.

        This way it would be avoidable to write lots of (x != null) as in Java.

        1. Aug 05, 2011

          What about the converse, i.e. (value != null), which occurs more often: how do we write it?

          !value?

          looks like broken Spanish

          1. Aug 05, 2011

            Anonymous

            Ups, yes, sorry, my intention was of course to use x? for (x != null) because it's used more often and

            looks quite readable.

            1. Aug 05, 2011

              !value? will still occur, and it looks strange, but you are right we should look into some ways of shortening null-checks

              1. Aug 05, 2011

                Anonymous

                I still think, the ? postfix is the most logical choice, because it mirrors the declaration syntax:

                Of course negation could use !?, but

                would look even stranger. So while

                may look a bit strange, it's quite logical.

                The prefix versions:

                don't look to nice either and lose the connection to the declaration syntax.

                Of course you could also add "unless" to the language to be able to write

                and at the same time improve readability for expressions like

                but I'm not sure if this would be a good idea...

                OTOH you have things like "!is", so maybe just allow to write

                1. Aug 05, 2011

                  Note that it mirrors the declaration syntax in a reversed way (well, like a mirror does):

                  at a declaration site ? means "may be null"

                  at use-site, you suggest, it means "not null"

                  The !if will not work, because if is an expression.

                  1. Aug 22, 2011

                    Anonymous

                    ! and ? look equally "strong" and should maybe be used for similar purposes...

                    Maybe use a different sign for negation, e.g. ^:

                    Then you could use ! for the null test:

                    instead of

                    and

                    instead of

                    1. Aug 23, 2011

                      Anonymous

                      In another thread, I suggested a prefix "@" or some other symbol, since most existing unary operators (!, ~, etc.) are prefix. So you would have:

                      if (@a) ...

                      if (!@a) ...

                      if (@a && !@b && @c && !@d) ...

                      Prefix "?" might also be a possibility, although I personally find "if (!?a)" difficult to visually parse. I prefer the prefix form to the postfix form, though.

              2. Jul 15, 2014

                Maybe, prefix !!x as (x != null) shortcut? It looks quite consistent with the postfix !!, and IIRC this is common null-check in Javascript.

                1. yesterday at 14:06:07

                  Well, this clashes cognitively with double negation.

                  1. yesterday at 15:57:19

                    Yes and I don't think that this counter-intuitive when you know about existence of such operator ("double negation is assertion"). And double negation is not something that you use commonly, in fact, the only use could be in case of some weird operator overloading.

                    Speaking of operator overloading... maybe it is possible to implement such feature with current syntax? Though it will require dangerous overriding of Any?.not, creating some intermediate value, and will allow compile-time !x expression for any type.

          2. Jun 29, 2014

            haha, good one

            "!= null" reads well and isn't too hard to type.

            the other suggestions look like punctuation soup. if something had to be done, I would just let `if (value)` mean `if (value != null)`. i know, this is something that horrible scripting languages do, but I don't think it's too bad. booleans are typically prefixed with "is," and nullable types shouldn't occur too often in code.

  8. Aug 22, 2011

    Anonymous

    1. What is the difference between "a?.b()" and "a?b()"? If it means the same: the first one is nicer to look at, but what can you do to make as easily typed as the second one in the IDE?
    2. What about a shorter syntax for "if (a != null) ...", maybe "if (a?) ..."?
    1. Aug 22, 2011

      1. a?.b() means

      if (a != null) a.b() else null

      And a?b() means

      if (a != null && a.b()) a else null

      2. See this branch of comments.

    2. Aug 22, 2011

      Anonymous

      ...ah, OK, 2. has already been discussed, sorry... 

  9. Aug 24, 2011

    re: npe().  Wow, you are really rubbing it in Java's face.  A function to recreate the least popular error of all times, so code can break at runtime instead of compile time.  I admire your brazenness.  

    1. Aug 24, 2011

      Well, I wouldn't put it that way

  10. Jan 11, 2012

    Is System.out nullable? That is just ... sad.

    System.out?.println("Hello, world\!")

    Any likelihood to special case idioms like this from the JDK? Although one could technically set out & err to null, it would be obscure. Were I reviewing "System.setOut(null)" in a fellow's code, I'd call them out on it.

    1. Jan 11, 2012

      Well, the standard library will hide this from you. To support other cases we are working on a facility that would know that Java types are not nullable sometimes.

  11. Jan 18, 2012

    I would add 4th item to the list of possible NPE sources:  Multithreading done wrong. At least, this might be a remark to 3rd point.

    Possible example:

    var len = 0 
    if(this.b != null) 
      // another thread changes this.b at this moment to null 
      // but compiler still thinks that this.b has value 
      len = this.b.length()// oops?
    1. Jan 18, 2012

      AFAIU, this situation is impossible. Kotlin wouldn't believe the null check if b is mutable. And if it isn't, the only possible change is from null to something else, not the other way around.

      I'll add this to the docs above.

      1. Jan 19, 2012

        Thank you for clarification!
        Does it mean that it's not possible to use ` ?. ` operator for accessing class property?
        As I understand, correct implementation must involve copying the value from property to synthetic local variable:

        val len = this.someNullableString?.length() 
         
        // must be implemented equally to: 
         
        val _tmp = this.someNullableString  // someNullableString can be safely set to null from another thread now 
        val len = if (_tmp != null) _tmp.length() else null;  // same as _tmp?.length()

        Is it implemented this way?

        1. Jan 19, 2012

          You can use ?. for a member property, because both the null-check and the call work on the same value (there's only one read-access to the property).

          In the byte code there's no need in a local variable, a simple DUP instruction is sufficient.

          1. Nov 24, 2012

            I am observing the following behavior (kotlin-plugin, WebDemo)

            Could you please clarify the reason for this behavior?

            Why does the null check behave differently depending on val/var?

            Thanks!

            1. Nov 26, 2012

              A val is guaranteed to never change, thus it is safe to rely on a check performed somewhere. A var may have changed since the check was performed.

              We will probably improve the analyzer and support local vars that don't change in fact. But now that case is not supported.

              1. Nov 26, 2012

                ok, so this primarily addresses concurrency issues, does it?

                It is a pity since there are many use cases where we know we are in a single threaded environment and there is no chance a var may become null. I am looking forward to the analyzer improvement, but I cannot imagine how this could be done.

  12. Feb 21, 2012

    Are nullable types somehow retained in bytecode? Is there a way to introspect the nullability of a property using reflection? Maybe the compiler could implicitly add some specific annotation to such properties? This could be useful in ORMs which could emit NOT_NULL statements in DDL automatically.

    1. Feb 21, 2012

      This is exactly what Kotlin does: we add annotations with complete type information

  13. May 16, 2012

    I have yet another question about null-safe design approach. Sorry if you've already covered it elsewhere.

    In Scala, Options (thus nullable types) are treated pretty much like collections: for non-null value we have a one-element collection; or we get Nil otherwise. This approach brings a couple of techniques I currently can't imagine my life without:

    • using monadic functions on nullable types, as you normally do with collections: 
    • returning values in flatMap, when working with collections:

    Now I can't imagine all such small code fragments implemented with IF-statements and elvis operators. So, how such things will be going in Kotlin?

    1. May 16, 2012

      All these operations can be defined as (extension) functions in Kotlin, and they are there in the library: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/nullable/Nullables.kt

      1. May 16, 2012

        Great news for me :) Thanks!

  14. Jul 02, 2012

    I found myself in situation like this:

    Here T possibly can be nullable and T? is always nullable. How can I make NPE to be thrown only if T is not nullable and event value is null?

    I mean somethig like this:

    upd: I've found solution for this particular case

    but there is still no way to call method with generic parameter with surely nullable argument and have npe only if argument is null and generic parameter is not nullable

  15. Oct 07, 2012

    How do you recommend dealing with external libraries, where Kotlin typically assumes that they are returning a value that might be null, whereas in reality they will never return null?

    For example, in the Google Guava libraries, BloomFilter.create(..) always returns a BloomFilter, but Kotlin assumes that it could be null, even though this will never happen.

    Should I just use the !! operator on the value returned by the function, or is there a better way to deal with this?

    1. Oct 07, 2012

      See it here: http://blog.jetbrains.com/kotlin/using-external-annotations/

      Meanwhile, we are working on a tool that would infer those annotations automatically. It will be available soon.

  16. Feb 09, 2013

    I'm new to Kotlin, but I really like its null-safety features with the various uses of '?'. It's all very consistent and elegant.

    But here's a suggestion: the only place where you don't use the ? symbol is in the keyword null itself. This is inconsistent (and seems old-fashioned, like the ugly days of C++) - and of course null hardly ever needs to be mentioned in code anyway.

    So: why not simply use the symbol ? itself:

    You could always deprecate null for the moment & remove it later.

    If this is possible, I would love Kotlin.

    1. Feb 09, 2013

      (deleted)

    2. Feb 12, 2013

      Thanks for your suggestion, but im my opinion, this would make the syntax cumbersome and unfamiliar where it need not be. Also, while unambigous for the compiler, it will be rather ambiguous for the eye.

  17. Apr 14, 2013

    Hi,

    Any reason why two '!'  in : 

    why not a single '!':

    is it just a preference or there is a explanation behind it ?

    1. Apr 14, 2013

      It's more visible and causes no confusion with negation.

      1. Jun 08, 2014

        Hmm... I'm not so sure about the non-conflation with negation. Consider the following:

        As one's eye moves hurriedly, one might mistakenly read the above as `line does not start with "//"`. The ?. operator already has a null-safety association, so wouldn't ??. be a better choice here?

        1. Jun 08, 2014

          This syntax has been around for a while. No one ever read this as 'line does not start with "//"'

  18. Oct 15, 2013

    It there any short "if null then NPE" operator?

    For example

    1. Oct 15, 2013

      Yes, there's a !! operator that throws an exception is the argument is null, the syntax is exactly as in your example above

      1. Oct 15, 2013

        Perfect, sorry I missed it in the docs - Thank you

  19. Jun 29, 2014

    > Note that this only works where b is immutable (i.e. a local val or a member val which has a backing field and is not overridable), because otherwise it might happen that b changes to null after the check.

    Is this why in Swift you have to `if let temp = value`? Hmm... maybe Kotlin should offer the same? However, if this is just to prevent multithreaded race conditions, then the restriction seems rather excessive. (The vast majority of code is not touching shared variables, moreover without locking, and code that is has enough potential dangers that it wouldn't matter much if this were another.)