Kotlin
2026-08-21 09:00
And gave NullPointerException as the example.
This unit delivers it.
Every guarantee here is bought by making the type system carry more information.
Java’s type system carries none of it.
So each half of the unit ends at the same boundary.
let and lateinit.Any, Unit and Nothing.They are different types.
To call methods on it.
To assign it to a non-null variable.
To pass it where a non-null value is expected.
A type describes the possible values and the operations available on them.
Java’s String claims to be a string and may be null.
So .length works sometimes and throws other times.
A type admitting a value on which none of its operations work
is not describing its values honestly.
None.
No wrapper objects. Checks at compile time.
The bytecode is what you would have written by hand.
Java needs three nested ifs, or one long && chain.
That second one works because of Nothing. Later in this unit.
One line replaces the instanceof-then-cast dance.
The syntax was chosen to look like shouting.
Not a joke — it should be visible in review.
Use it only where you know something the compiler cannot.
Never chain it. a!!.b!!.c throws on a line —
and the stack trace tells you the line, not which assertion failed.
For anything longer, if (x != null) with a smart cast reads better.
kotlin.UninitializedPropertyAccessException:
lateinit property myService has not been initialized
Names the property. A great deal better than a bare NPE.
An extension is a static function taking the receiver as a parameter.
A parameter can be null. No dispatch, nothing to fail.
If a call on a nullable value compiles without ?.,
the function has a nullable receiver.
Kotlin’s null safety needs to know whether a value can be null.
Java does not record that.
Everything from Java is nullable. Safe, and unusable — every call would need a safe call, including the vast majority that never return null.
Everything from Java is non-null. Convenient, and a lie — an NPE becomes possible in code the compiler certified safe.
A platform type. You cannot declare one.
It means “nullability unknown”, and Kotlin allows both uses.
Not at the call site.
At the point where a platform value is assigned to a non-null type.
So the error surfaces near the mistake.
The guarantee is complete within Kotlin.
At the boundary it degrades to a documented, visible compromise.
A language insisting on purity here would be safer on paper and adopted by nobody.
Java has int and Integer and makes you choose.
Kotlin has Int, and emits a JVM int wherever it can.
collections · generics · nullable types
One cause: the JVM cannot put a primitive there.
So Int? is Integer — a nullable number is a boxed number.
Not even widening. Java does it silently.
With implicit conversion, whether these compare equal depends on rules most people cannot recite.
A small daily cost.
A whole category of confusing bug, removed.
Arithmetic operators are overloaded for mixed types.
1L + 1 works. The rule bites on assignment and comparison.
The supertype of all non-null types.
java.lang.Object, minus the null.
Java’s Object might be nothing at all. Any cannot be.
Unlike void, it is a real type with a value.
Java needs Void and an explicit return null.
The type of an expression that never returns.
Elvis needs compatible types. Nothing fits with anything.
Which is why throw on the right worked earlier. That was Nothing all along.
A statement about behaviour, checked by the compiler.
Not documentation that may be wrong.
The same object may be referenced elsewhere as mutable.
Read-only is a view, not a property of the object.
It is not a thread-safety guarantee.
The reference is restricted.
The object is not.
Can it be null?
Read-only or mutable?
Can its elements be null?
The lambda form removes the loop-and-assign pattern entirely.
filter and map are available on arrays.
They return lists — which is usually what you wanted.
Java interop. vararg.
Otherwise: no read-only variant, no useful toString, identity equality.
Three reasons a list is nearly always better.
Nothing is not a curiosity — it is why ?: throw compiles.Operator Overloading and Other Conventions.
in did double duty. to was a function, not syntax.
Both are one mechanism: a specifically named function giving your type built-in syntax.
Kotlin · The Kotlin Type System