What does the exclamation point after the name of a type mean?

10

I've seen a lot in Kotlin types marked with an exclamation mark at the end. Especially when using Java APIs.

Something like

CharSequence!

What does this mean?

    
asked by anonymous 27.07.2018 / 02:17

2 answers

8

Indicates that the type can be null. In Kotlin types can not be null by default. But in Java they can at least types by reference. So you need to have a type that allows you to interoperate with this Java condition.

The language has to respect Java's decision and therefore to give more robustness to its own code and even to gain performance it is necessary to inform the compiler when there is an exception to the non-zero guarantee rule.

Do not use if you are not interoperating with Java. In fact in most cases it is best that you have a way to ensure the non-null type (some operation that checks manually and can ensure that this condition will not change to null after) and use a common type.

There is still the type indicator ? which makes the type always accept null and then you have to check the status always before using. ! does not. It allows you to understand that it is not null in your Kotlin code, but still interoperate in Java. Before accessing in Kotlin you need to ensure that it is valid, but not after. The ? allows you to undo the value, ! does not allow it.

There are cases that Java can give clues to better infer the possible situation and already ensure that it is not null. There are cases where the type is inferred as ! (possibly nullable).

I do not have enough experience, but I think if the data is changeable and shared with Java, it works the same because you can never trust it in competing environments or you pass control of execution to Java in the middle of processing. And in OOP it's easy to do this without realizing it.

It ends up being part of the data type. In fact in Kotlin is called the platform type (in allusion to Java as platform). I would need to search further to understand whether the compiler inserts checks in runtime or not to ensure that output to Java guarantees some verification. It makes sense to do so, but I can not guarantee and superficially I did not find anything, so just doing an extensive test.

Documentation .

The !! operator forces a NullPoiterException error if the object is null in this case (posing as a curiosity).

There is something similar in C # 8, but it gives assurance that it is not null. Some people like to call it dammit operator .

    
27.07.2018 / 02:23
3

It means that you are dealing with a platform type : a type coming from Java that may or may not be null.

The Kotlin compiler always tries to search for nullability annotations and infer whether a type may be null or not.

If annotations are present, the type will be represented as nullable ( CharSequence? ) or not ( CharSequence ).

If the annotations are not present, it will be considered a platform type ( CharSequence! ). In practice this means that null checks will be less restricted. When methods are called on these types, no compile-time errors are generated, but run-time errors may occur due to null checking that Kotlin generates in order to not propagate nulls.

Consider the following assignment, interoperating with Java:

// Chamando código Java sem anotação de nulabilidade
val resultWithPlatFormType = myJavaObject.myJavaMethod() 

The following call may generate a run-time error:

// Lançará uma exceção caso resultWithPlatFormType seja nulo
resultWithPlatFormType.trim()

Note that platform types are not "annotated", that is, the language has no formal way of representing them explicitly. When one of these types is assigned to a Kotlin variable, we can use type inference or explicitly choose how we want to treat the value:

val inferred = myJavaObject.myJavaMethod() // Será inferido como platform type
val notNull: String = myJavaObject.myJavaMethod()  // Funciona, mas pode falhar em tempo de execução
val nullable: String? = myJavaObject.myJavaMethod() // Sempre funciona
    
27.07.2018 / 15:40