Another advantage over Scala is that Kotlin compiler puts null checks on boundaries between Java and Scala, so even if your code pretending to be safe breaks in runtime, you'll catch error as soon as possible, this null won't leak into your internals to bite you tomorrow.
But that's certainly a thing that could be improved. Majority of Java parameters/return values nullability could be automatically inferred by analyzing bytecode.
With scala the NPE could appear after the null crossed the java/scala boundary deep into scala code where you'd assume it should be impossible to get an NPE. It can sometimes be hard to fix because the problem is far away from the cause.
[1] https://kotlinlang.org/docs/reference/java-interop.html#null...
>If we choose a non-null type, the compiler will emit an assertion upon assignment. This prevents Kotlin's non-null variables from holding nulls. Assertions are also emitted when we pass platform values to Kotlin functions expecting non-null values etc. Overall, the compiler does its best to prevent nulls from propagating far through the program (although sometimes this is impossible to eliminate entirely, because of generics).
Methods marked `nonnull` can still be nil sometimes, it's just a promise. Hard bugs to fix. Found one in an Apple framework where I could not think of anything else than comparing the address with 0x00000000 to see if it was nil.
This feels like a trad-off between ease-of-use/adoption. It's effectively undefined behavior to reference a nullable type from Java. Another way to consider this is that it's not necessarily worse than working natively in Java, but it can over time be better. This trade-off seems reasonable, as there is no great answer to this problem, but it's almost identical to Java's auto-unboxing of Integer types to int.
So for JPA entities, each field is marked as nullable, because in Java it is. If we need a null checked version we map it from the nullable fields object to a object that has been null checked and has non-nullable fields (where appropriate).
Wrappers can be written to interact with more traditional Java libraries that do a similar null check and mapper, keeping platform types from propergating intro other layers of the system.
Platform types make interopt way easier, but if you are concerned with null safety you have to write some code to deal with them.