What does the exclamation mark mean after a guy’s name?

Asked

Viewed 753 times

10

I have seen a lot in Kotlin types marked with an exclamation mark at the end. Especially when I use Java’s API.

Something like

CharSequence!

What does that mean?

2 answers

8


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

The language needs to respect the decision of Java and so to give more robustness to its own code and even gain performance it is necessary to inform the compiler when there is an exception to the no null guarantee rule.

Do not use if it is not interoperable with Java. In fact in most cases it is better to have a way to guarantee the non-null type (some operation that checks manually and can ensure that this condition will not change to null later) 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. The ! no. 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, the ! does not allow to do so.

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

I don’t have enough experience, but I think if the data is mutable and shared with Java, it’s still because you can’t ever trust it in concurrent environments or that you pass control of the execution to Java in the middle of the processing. And in OOP it’s easy to do it without realizing it.

It ends up being part of the data type. In fact in Kotlin it is called a platform type (alluding to Java as a platform). I would need to research further to understand if the compiler inserts verification on Runtime or not to ensure that output to Java ensures some verification. It makes sense to do it this way, but I can’t guarantee and superficially I didn’t find anything, so I’m just doing an extensive test.

Documentation.

There is the operator !! which forces an error of NullPoiterException if the object is null in this case (putting as 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.

  • Two questions launches an Exception, in the case of only one query, which happens if a variable receives a null value at runtime, not being possible to predict at compile time?

  • @Guilhermecostamilam throws an exception, running it like Java. Note that the !! is an operator, see the other question there to understand, I wrote about it more to introduce the other question. There is still doubt or it was clear?

  • So no exclamation is build error, an exclamation allows null and can generate an exception during execution, two exclamations allows null but generates an exception in running equating this occurs, got it right?

  • 1

    Trying to put a null in a type gives build error. With an exclamation in type allows the null and can generate the exception, two exclamations is not allowing exception, generates the exception if null, because this is an operator. There is still the ? which defines that the type may be nullable. See https://kotlinlang.org/docs/reference/null-safety.html#nullable-types-and-non-null-types. I’m going to supplement the answer to make it more complete and clear that this exclamation annotation has to do with iteroperability.

  • @Guilhermecostamilam see if it’s improved. Improved my understanding.

  • With your editing and the other answer I think I got it, thanks

Show 1 more comment

3

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

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

If annotations are present, the type shall be representable 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 in these types, no errors are generated at compile time, but errors can occur at runtime due to null checking that Kotlin generates 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 an error at runtime:

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

Note that the platform types are not "anonable", that is, the language does not have a 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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.