0Pricing
Android Academy · Lesson

Nullable vs Non-Null Types

The ? type marker.

Nullable vs Non-Null Types is a free Android 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 Android 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

Many crashes in Android apps come from one mistake: using a value that is actually missing. In other languages this becomes a dreaded NullPointerException at runtime.

Kotlin tackles this at compile time. The type system tracks which values may be null and which never can. This lesson introduces the foundation of that system.

Non-Null Types

By default, a Kotlin type cannot hold null. A String always points to a real string.

If you try to assign null to it, the code will not even compile. This is the safe default.

fun main() {
    val name: String = "Ada"
    println(name.length)
}

Null Is Rejected

Watch what happens when you try to put null into a non-null type.

The compiler stops you immediately. You never reach runtime with a hidden bug.

val name: String = null  // Compile error:
// Null can not be a value of a non-null type String

Nullable Types with ?

Sometimes a value really might be missing, like a user's optional middle name. You opt in by adding ? to the type.

A String? can hold a real string or null. The question mark marks the type as nullable.

fun main() {
    val middleName: String? = null
    println(middleName)
}

Two Different Types

String and String? are not the same type. The second is a wider type that includes the value null.

This distinction is what lets the compiler protect you. It knows exactly where null can appear.

val sure: String = "hello"
val maybe: String? = "hello"
// maybe could later be null; sure never can

You Can't Use Nullable Directly

The compiler will not let you call a method on a nullable value without checking it first.

Because middleName could be null, calling .length on it is a compile error. You must handle the null case.

val middleName: String? = null
println(middleName.length)
// Error: only safe (?.) or non-null (!!) calls allowed

Checking with if

The simplest way to use a nullable value is to check it with an if condition.

Inside the branch where you proved it is not null, Kotlin smart-casts it to a non-null type, so .length works.

fun main() {
    val text: String? = "Kotlin"
    if (text != null) {
        println(text.length)
    }
}

Smart Casts

After a successful null check, the compiler remembers the value is not null for the rest of that block. This is called a smart cast.

You did not write any conversion. Kotlin tracked it for you automatically.

fun describe(s: String?) {
    if (s == null) return
    // s is now treated as String here
    println("Length is " + s.length)
}

Function Parameters

Whether a parameter is nullable is part of the function's contract. A non-null parameter promises callers it will never receive null.

A nullable parameter signals that missing input is expected and handled.

fun greet(name: String) {
    println("Hi, " + name)
}
// greet(null) would not compile

Return Types Can Be Nullable

A function may return null to signal that nothing was found. Mark its return type with ?.

Callers then know they must check the result before using it.

fun firstChar(s: String): Char? {
    if (s.isEmpty()) return null
    return s[0]
}

Default to Non-Null

A good rule: prefer non-null types. Only add ? when a value can genuinely be absent.

This keeps your code honest. The fewer nullable types you have, the fewer null checks you need later.

// Prefer this:
val score: Int = 0
// Over this, unless null is meaningful:
val maybeScore: Int? = null

Quick Check

Test your understanding of nullable versus non-null types.

Recap

Kotlin types are non-null by default and reject null at compile time. Add ? to make a type nullable when a value may be missing.

You cannot use a nullable value directly. A null check smart-casts it to non-null so you can safely use it. Next you will learn shorter ways to handle nullables.

Frequently asked questions

Is the “Nullable vs Non-Null Types” lesson free?

Yes — the full text of “Nullable vs Non-Null Types” is free to read here on the web, and the Android 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 Android Academy course, upgrade to CoddyKit PRO.

What will I learn in “Nullable vs Non-Null Types”?

The ? type marker. You practise Android 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 Android Academy?

No prior experience is required. Android 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 vs 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 Android Academy lesson?

Yes. Every Android 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

  1. Nullable vs Non-Null Types
  2. Safe Calls and Elvis
  3. let, also, and Scope Functions
  4. Avoiding NullPointerExceptions
← Back to Android Academy