13

I'm very aware of the Kotlin null safeness. I Know "?" after a type (ex: Int?) can be used to declare a variable or value as nullable. I also know that !! operator is used to return a non-null value or throw NPE.

In general, a type with "?" after it will be nullable, and without "?" is a non-null. But I have seen when I'm inspecting some variables something like this:

var myVariable: Int!

It happens when you use java code from kotlin code.

//java code
public class Foo {
    public Integer calcNumber()
    {
        return null;
    }
}

If I use the function Foo.calcNumber()

//kotlin code
val meh = Foo().calcNumber()
print(meh)

the value meh is inspected as Int!, not Int nor Int?. Obviously here the value meh can be null, but it is not correctly "detected" by the "IDE".

As

var a: Int! = 10

is invalid, my question is: What does exactly mean types with "!"?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Raymond Arteaga
  • 4,355
  • 19
  • 35
  • "Platform Types" - https://kotlinlang.org/docs/reference/java-interop.html#notation-for-platform-types ; the linked question should given more information. – user2864740 Jul 05 '18 at 04:29

1 Answers1

15

The Type! notation is called a Platform Type and is critical for Interoperability with the weaker-typed Java; it means "the null-ability is unknown" and it allows for relaxed null-ability enforcement. I found the examples in the linked question underwhelming.. although all the information is there.

The following program is accepted as type-safe, as Kotlin allows the type of the x/Int! expression to be used as "Int or Int?".

var x = JavaIntegerList.get(0); // Int! type inferred by Kotlin
var y: Int? = x;
var z: Int = x;

However, the assignment to z (Int) will fail at run-time if x evaluates to null. (For class implementation types, the NPE may delayed to usage: basically, Kotlin chooses to 'get out of the way'.)

It's thus designed for cases when it is known that the value "cannot" be null in a valid program, although the value comes from Java outside of the Kotlin type system. Highly applicable to int-box-Integer in Java, although it is valid for any class type / value coming in from Java. If the Java code can return null, it is safest to put the value into a Type? immediately and then correctly deal with the null-ability.

Compare this to the Java code with similar run-time failure semantics:

// Java
Integer x = JavaIntegerList.get(0);
Integer y = x;  // "No OP" - all class types in Java are null-able
int z = (int)x; // kaboom *at run-time* if x is null!

While simple to show with ints, as in this example, this issue is not strictly related to Java's int/Integer types. The document linked above shows a case of String! being implicitly used, giving the example that item.substring(1), where item is a String! is allowed/type-safe but will fail at run-time if item evaluates to null.

user2864740
  • 60,010
  • 15
  • 145
  • 220