Nullable and Non-Null Types
The type system basics.
Nullable and Non-Null Types is a free Kotlin Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Null Safety Matters
The infamous NullPointerException has crashed countless programs. Kotlin tackles this problem head-on by making nullability part of the type system.
In Kotlin, the compiler knows whether a value can be null or not, and it forces you to handle the possibility before you run into trouble.
Non-Null Types
By default, every type in Kotlin is non-null. A variable of type String can never hold null.
This guarantee is enforced at compile time, so you can use the value freely without checks.
fun main() {
val name: String = "Alice"
println(name.length)
}Assigning Null Is Rejected
Try to put null into a non-null type and the compiler stops you immediately.
The line below would fail to compile because String does not accept null:
val name: String = null→ error
fun main() {
val city: String = "Paris"
// val broken: String = null // compile error
println(city)
}Nullable Types
To allow null, add a question mark after the type: String?.
This is a nullable type. It can hold either a real value or null.
fun main() {
val maybeName: String? = null
println(maybeName)
}Nullable vs Non-Null
The two declarations look almost identical but behave very differently:
val a: String→ never nullval b: String?→ might be null
The single ? changes the whole contract of the variable.
fun main() {
val a: String = "hi"
val b: String? = "hi"
println(a)
println(b)
}The Compiler Guards Nullable Access
You cannot call methods directly on a nullable value. The compiler refuses, because the value might be null.
The commented line below would not compile:
maybe.lengthon aString?→ error
fun main() {
val maybe: String? = "text"
// println(maybe.length) // compile error
println(maybe)
}Checking for Null
One simple way to use a nullable value is an explicit if check.
Inside the if block, Kotlin knows the value is not null and lets you use it safely.
fun main() {
val maybe: String? = "hello"
if (maybe != null) {
println(maybe.length)
}
}Null in Function Parameters
Parameter types also follow the rule. A parameter typed String must receive a real value, while String? accepts null.
This makes function signatures self-documenting about what they accept.
fun greet(name: String?) {
if (name != null) {
println("Hello, " + name)
} else {
println("Hello, guest")
}
}
fun main() {
greet("Mia")
greet(null)
}Nullable Return Types
Functions can return nullable types to express that a result may be missing.
The caller is then forced to handle the possible null before using the result.
fun firstChar(text: String?): Char? {
if (text == null || text.isEmpty()) return null
return text[0]
}
fun main() {
println(firstChar("Kotlin"))
println(firstChar(null))
}Default Inference
When you assign a literal, Kotlin infers a non-null type automatically.
val n = "text"→ inferredString
To make it nullable you must declare the type explicitly with ?.
fun main() {
val n = "text" // inferred String (non-null)
val m: String? = "text" // explicit nullable
println(n.length)
println(m)
}Putting It Together
The type system splits values into two clear groups:
- Non-null: always safe to use
- Nullable: must be handled before use
This distinction moves null bugs from runtime crashes to compile-time errors.
fun main() {
val safe: String = "always here"
val risky: String? = null
println(safe.uppercase())
if (risky != null) println(risky.uppercase()) else println("no value")
}Quick Check
Test your understanding of nullable and non-null types.
Recap
You learned the foundation of Kotlin null safety:
- Every type is non-null by default
- Adding
?creates a nullable type - The compiler blocks unsafe access to nullable values
- An
if (x != null)check lets you use the value safely
Next you will learn the concise operators that make working with nullables effortless.
Frequently asked questions
Is the “Nullable and Non-Null Types” lesson free?
Yes — the full text of “Nullable and Non-Null Types” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “Nullable and Non-Null Types”?
The type system basics. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Nullable and Non-Null Types” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Nullable and Non-Null Types
- Safe Calls and Elvis
- The !! Operator
- Platform Types