Model absence in the type
String promises a non-null value; String? permits either a string or null. An empty string is still a value, so deciding whether blank input counts as absent is a separate business rule.
fun displayName(raw: String?): String {
if (raw == null) return "Guest"
return raw.trim().ifEmpty { "Guest" }
}
fun main() {
println(displayName(null))
println(displayName(" Asha "))
}
After the null check and early return, the compiler treats the local parameter as non-null. Outputs are Guest and Asha. This narrows the value only in code paths where the check guarantees safety.
Avoid making every property nullable simply to postpone initialization decisions. A required user ID should fail validation at the boundary rather than spread null checks through every function. Conversely, an optional nickname should not be represented by a fabricated default that loses the distinction between missing and supplied data.
Exercise
Model a profile with a required ID and optional nickname. Implement a display label without !!, testing null, blank, and populated nicknames.
Check: explain why a non-null type does not guarantee a nonblank or otherwise valid string.