1

In the code below. I found in Intellij Idea compiler that val a and val b by default are "val a: StringBuilder" & "val b: StringBuilder!"

what is the difference between the two? What's the difference between StringBuilder and StringBuilder! ? Thank you :)

fun main(){
    val a = StringBuilder().apply { // by default is val a : StringBuilder
        append("Hello ")
        append("from me")
    }
    println(a)

    val b = StringBuilder().run { // by default is val b : StringBuilder!
        append("Hello ")
        append("from me")
    }
    println(b)
}
1
  • apply will return itself (that it was called on). run will return the result of last line, i.e. it will propagate the return statement of append("from me") to b. Since the append() is defined in Java, and has no Nullability information, it is considered as JVM platform type in Kotlin. Commented Oct 10, 2020 at 8:29

1 Answer 1

3

The ! indicates a platform type. It means that the compiler can't tell whether the type is nullable or not, because it comes from Java (or another JVM language), which doesn't make the distinction between nullable and non-nullable types, and doesn't have an annotation (@Nullable or @NonNull) to indicate that.

As a result, the compiler won't be able to make its usual null checks, so you should take care.

If you know (from the documentation, or looking at the Java code, or whatever) whether the value could be null or not, it's a good idea to specify the type explicitly (as either nullable with a trailing ?, or non-nullable without).

In this case, the difference is that apply() returns the value it was called on; that's all Kotlin, so the compiler knows its type. However, run() returns the last value in the lambda, which is the result of the last append() call. That method is defined in Java (since StringBuilder is part of the Java standard library), so the compiler can't tell whether it's nullable or not. But it's clear from the documentation that the method simply returns the StringBuilder it was called on, and so cannot be null. So for safety, you could specify an explicit StringBuilder type (i.e. non-nullable) for b.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.