45

I have a bunch of beans that have nullable properties like so:

package myapp.mybeans;

data class Foo(val name : String?);

And I have a method in the global space like so:

package myapp.global;

public fun makeNewBar(name : String) : Bar
{
  ...
}

And somewhere else, I need to make a Bar from the stuff that's inside Foo. So, I do this:

package myapp.someplaceElse;

public fun getFoo() : Foo? { }
...
val foo : Foo? = getFoo();

if (foo == null) { ... return; }


// I know foo isn't null and *I know* that foo.name isn't null
// but I understand that the compiler doesn't.
// How do I convert String? to String here? if I do not want
// to change the definition of the parameters makeNewBar takes?
val bar : Bar = makeNewBar(foo.name);

Also, doing some conversion here with foo.name to cleanse it every time with every little thing, while on the one hand provides me compile-time guarantees and safety it is a big bother most of the time. Is there some short-hand to get around these scenarios?

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336
  • 1
    I believe that the compiler will only prove that `foo !=` null if it's within the conditional block. You could try replacing your null check with `if (foo != null) { ... }` – fmt Sep 06 '16 at 13:05
  • 2
    Possible duplicate of [In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them](http://stackoverflow.com/questions/34498562/in-kotlin-what-is-the-idiomatic-way-to-deal-with-nullable-values-referencing-o) – Jayson Minard Sep 06 '16 at 14:47

2 Answers2

52

You need double exclamation mark like so:

val bar = makeNewBar(foo.name!!)

As documented in Null Safety section:

The third option is for NPE-lovers. We 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.

miensol
  • 39,733
  • 7
  • 116
  • 112
  • This will throw `NullPointerException` if `foo.name` is null. It seems that OP wants to do nothing in that case, not throw. – fmt Sep 06 '16 at 13:06
  • Thank you. I was putting the double-exclamation mark in the wrong place. I had read about it but was using `foo!!.name` and it wouldn't compile and I was loosing hope. Many thanks. 11 more minutes before I can mark this answer. – Water Cooler v2 Sep 06 '16 at 13:06
  • 1
    @Actorclavilis Yes, thank you. That's the behavior I want. I mean, I know and can guarantee that that won't happen so that's the behavior I am after, anyway. I'd read about this operator the NPE-operator, they call it, but wasn't sure where to put it in the expression. – Water Cooler v2 Sep 06 '16 at 13:07
6

You could use an extension:

fun <T> T?.default(default: T): T {
    return this ?: default
}

Then use it like this:

fun getNonNullString(): String {
    return getNullableString().default("null")
}
Sir Codesalot
  • 7,045
  • 2
  • 50
  • 56