What is Null Safety in Kotlin?
Null Safety in Kotlin is the language feature that separates variables that can hold null from variables that cannot hold null. This reduces the chance of a NullPointerException by making nullability visible in the type itself.
If you are a Java developer, you might have definitely come across the atrocities of NullPointerException it creates during real time. NullPointerException is so popular as NPE (NullPointerException), since it costed billions of dollars to companies. Kotlin is so concerned about this, and made its type system in such a way that it eliminates the usage of NullPointerException, unless you want it explicitly. Thank you Kotlin.
In plain terms, Kotlin asks you to decide at declaration time whether a value is allowed to be null. A normal type such as String is non-nullable. A nullable type such as String? can hold either a String value or null.
Kotlin could never throw a NullPointerException unless you ask for it.
A more precise way to say this is: Kotlin prevents many common null errors at compile time, but a NullPointerException can still happen in specific cases. These cases include using !!, explicitly throwing an exception, calling Java code that returns unexpected null values, or working with inconsistent data.
Of course there are ways you might give NullPointerException a chance to live one more Exception again. Let us see how could this happen :
- When you ask for a NullPointerException explicitly
- to throw a NullPointerException or
- use !! operator. This operator comes with a disclaimer for usage : You have been warned! And yet you chose to live with NullPointerException.
- From Outside Kotlin
- You may be aware that you can run external Java code in your application. And this external Java Code is not NullPointerException proof, unless you make it so.
- Data inconsistency
For the official reference, see Kotlin’s documentation on null safety. Android learners may also find the Android Developers codelab on Kotlin nullability useful.
How Kotlin handles Null Safety ?
Following are some of the ways to handle Null Safety in Kotlin.
- Differentiate between nullable references and non-nullable references.
- User explicitly checks for a null in conditions
- Using a Safe Call Operator (?.)
- Elvis Operator (?:) : If reference to a val is not null, use the value, else use some default value that is not null
The sections below explain each approach with a small Kotlin program. The main ideas are nullable types, explicit null checks, safe calls, Elvis operator, and the not-null assertion operator.
Differentiate between Nullable and Non-nullable References in Kotlin
Kotlin’s type system can differentiate between nullable references and non-nullable references. ? operator is used during variable declaration for the differentiation.
To make a variable hold a null value, follow the below example and observe the usage of ? in the program
Kotlin Program – example.kt
fun main(args: Array){
var a: String = "Hello !" // variable is declared as non-null by default
println("a is : $a")
// kotlin prevents you assign a null to a non-nullable variable
// a=null //assing null to a causes complilation error
var b: String? = "Hi !" // variable is declared as nullable
println("b is : $b")
b = null
println("b is : $b")
}
Output
Compilation completed successfully
a is : Hello !
b is : Hi !
b is : null
Here, a is declared as String, so it cannot be assigned null. The variable b is declared as String?, so Kotlin allows b = null.
| Kotlin type | Can hold null? | Example |
|---|---|---|
String | No | var name: String = "Kotlin" |
String? | Yes | var name: String? = null |
Int | No | var count: Int = 10 |
Int? | Yes | var count: Int? = null |
Explicitly Check for Null before Accessing Nullable Values in Kotlin
If condition is an expression in Kotlin and hence can return a value. We may use this to explicitly check for a null and return a value in a single statement.
In the below example, we shall check if the variable ‘str’ is null and access the properties of str if not null.
Kotlin Program – example.kt
fun main(args: Array){
var b: String? = "Hello" // variable is declared as nullable
var blen = if(b!=null) b.length else -1
println("b is : $b")
println("b length is : $blen")
b = null
println("b is : $b")
blen = if(b!=null) b.length else -1
println("b length is : $blen")
}
Output
Compilation completed successfully
b is : Hi !
b length is : 4
b is : null
b length is : -1
The code block declares b with the value "Hello". For that exact code, the first length is 5. The idea remains the same: when b is not null, use b.length; when b is null, use -1.
Kotlin performs a smart cast after a successful null check in simple cases. Inside the if (b != null) branch, Kotlin treats b as a non-null value, so b.length is allowed.
Kotlin Safe Call Operator ?. for Nullable Properties and Functions
The safe call operator returns the variables property only if the variable is not null, else it returns null. So the variable holding the return value should be declared nullable. Following is the example program where a safe call is made with the variable b on property length.
Kotlin Program – example.kt
fun main(args: Array){
var b: String? = "Hi !" // variable is declared as nullable
var len: Int?
len = b?.length
println("b is : $b")
println("length is : $len")
b = null
len = b?.length
println("b is : $b")
println("length is : $len")
}
Output
Compilation completed successfully
b is : Hi !
length is : 4
b is : null
length is : null
The expression b?.length has the type Int?, not Int, because the result may be a number or null. This is why the example uses var len: Int?.
Safe calls are also useful when reading nested nullable values. For example, if user or address can be null, the expression user?.address?.city returns null safely instead of throwing an exception.
val city: String? = user?.address?.city
Kotlin Elvis Operator ?: for Default Values when a Reference is Null
If reference to a variable is not null, use the value, else use some default value that is not null. This might sound same as explicitly checking for a null value. But the syntax could be reduced and is given below.
Kotlin Program – example.kt
fun main(args: Array){
var b: String? = "Hello" // variable is declared as nullable
var blen = b?.length ?: -1
println("b is : $b")
println("b length is : $blen")
b = null
println("b is : $b")
blen = b?.length ?: -1
println("b length is : $blen")
}
Output
Compilation completed successfully
b is : Hello
b length is : 5
b is : null
b length is : -1
In b?.length ?: -1, Kotlin first evaluates b?.length. If the value is not null, that value is used. If the value is null, the expression returns -1.
The Elvis operator is often cleaner than writing a full if expression when you only need a default value.
val displayName = userName ?: "Guest"
val length = message?.length ?: 0
How to get a NullPointerException explicitly ?
Despite the safety measures Kotlin provides to handle NPE, if you need NPE so badly to include in the code, you have it. Following are the ways
- Throw an NPE if reference is null using ( !! ) operator
- During type casting (safely)
Kotlin Not-null Assertion Operator !! and NullPointerException Risk
Consider the following example to throw a NullPointerException using !! operator.
Kotlin Program – example.kt
fun main(args: Array){
var b: String? = "Hello" // variable is declared as nullable
var blen = b!!.length
println("b is : $b")
println("b length is : $blen")
b = null
println("b is : $b")
blen = b!!.length
println("b length is : $blen")
}
Output
Compilation completed successfully
b is : Hello
b length is : 5
b is : null
Exception in thread "main" kotlin.KotlinNullPointerException
at ArrayaddremoveKt.main(Arrayaddremove.kt:9)
The operator !! tells Kotlin: “I am sure this value is not null.” If the value is actually null, the program fails at runtime. Use !! only when you have a strong reason and when a failing program is acceptable for that situation.
Kotlin Safe Cast as? for Nullable Type Casting
Null safety also matters during type casting. A normal cast with as can fail if the value is not of the expected type. A safe cast with as? returns null instead of throwing a cast exception.
fun main() {
val value: Any = 25
val name: String? = value as? String
println(name)
}
null
Here, value is an Int, not a String. Because the code uses as?, the result is simply null.
Kotlin Null Safety Operators Quick Reference
| Operator or form | Meaning | Example |
|---|---|---|
? | Makes a type nullable | var name: String? |
if (x != null) | Checks null explicitly | if (name != null) name.length else 0 |
?. | Calls a property or function only if the value is not null | name?.length |
?: | Returns a fallback value when the left side is null | name?.length ?: 0 |
!! | Forces a nullable value to be treated as non-null | name!!.length |
as? | Returns null if a cast is not possible | value as? String |
Kotlin Null Safety Practices for Cleaner Code
- Use non-nullable types by default. Make a type nullable only when null is a valid state.
- Prefer safe calls and Elvis operator for simple nullable expressions.
- Avoid using
!!as a quick fix. It moves the risk from compile time to runtime. - When calling Java code from Kotlin, check whether the returned value can be null and handle it carefully.
- Choose meaningful default values. For example, an empty string, zero, or
-1should be used only when that value is valid for the program logic.
Kotlin Null Safety FAQs
What does String? mean in Kotlin null safety?
String? means the variable can hold either a String value or null. Without the question mark, String is non-nullable and Kotlin does not allow assigning null to it.
What is the difference between ?. and !! in Kotlin?
?. is the safe call operator. It returns null if the receiver is null. !! is the not-null assertion operator. It throws a runtime exception if the value is null. Use ?. for safe handling and avoid !! unless failure is intentional.
When should I use the Elvis operator ?: in Kotlin?
Use ?: when you want a default value for a nullable expression. For example, name?.length ?: 0 returns the name length if name is not null, otherwise it returns 0.
Can Kotlin still throw a NullPointerException?
Yes. Kotlin can still throw a NullPointerException in cases such as using !! on a null value, explicitly throwing the exception, interacting with Java code that returns null unexpectedly, or working with inconsistent initialized data.
Is a nullable type in Kotlin the same as an optional value?
A nullable type represents a value that may be null. It is similar in purpose to optional-value handling in some languages, but Kotlin expresses it directly in the type system using ?, such as Int? or String?.
Editorial QA Checklist for Kotlin Null Safety Examples
- Verify that every nullable variable uses the
?suffix in the type declaration. - Check that code examples using
?.store the result in a nullable type when required. - Confirm that examples using
?:explain the fallback value clearly. - Confirm that the
!!example is presented as a runtime-risk example, not as recommended practice. - Check that Java interoperability is mentioned because Java APIs can still introduce null values into Kotlin code.
Kotlin Null Safety Tutorial Summary
In this Kotlin Tutorial – Kotlin Null Safety, we have learnt what Null Safety is, differences between nullable references and non-nullable references, user explicitly checks for a null in conditions, using a Safe Call Operator (?.) and Elvis Operator (?:).
The most important point is to choose the correct type first. Use Type when a value must never be null, and use Type? only when null is a valid value. Then use explicit checks, safe calls, Elvis operator, and safe casts to handle nullable values clearly.
TutorialKart.com