Skip to content

Beginner · Null safety and object-oriented Dart · topic 5 of 50 · 30 min

Sound null safety

Explanation

In Dart 3, a variable of type String can never be null; String? can. The compiler forces you to handle possible nulls with ?. (safe access), ?? (default value), ??= (assign if null), flow analysis after a null check, or ! (which throws if the value is null). late promises a non-null value will be set before use, and required marks named parameters that must be passed.

Why null safety?

null means "no value". In many older languages any variable could be null, and using it caused crashes such as "Null check operator used on a null value" or "NoSuchMethodError: The getter 'length' was called on null". Since Dart 3, null safety is always on and sound: if the type says a value is not null, it really is never null at run time. The compiler checks this for you.

Nullable and non-nullable types

dart
void main() {
  String name = 'Asha';
  // String bad = null;        // error: a value of type 'Null' can't be assigned
  String? nickname;            // nullable, starts as null

  print(name.length);          // 4
  // print(nickname.length);   // error: the property 'length' can't be accessed on 'String?'
  print(nickname?.length);     // null
}
Add ? to a type to allow null. Without it, null is impossible.

The null-aware operators

OperatorMeaningExample
?.Access only if not null, else the result is nulluser?.email
??Use a default if the left side is nullnickname ?? 'Guest'
??=Assign only if the variable is currently nullcity ??= 'Delhi'
!Assert not null; throws if it is nullnickname!.length
?[]Index only if the collection is not nullitems?[0]
dart
void main() {
  String? referral;
  final code = referral?.trim().toUpperCase() ?? 'NONE';
  print(code);                 // NONE

  int? retries;
  retries ??= 3;
  print(retries);              // 3
}
Chain ?. and finish with ?? to get a non-null result.

Flow analysis (type promotion)

dart
int lengthOrZero(String? text) {
  if (text == null) {
    return 0;
  }
  return text.length;          // text is promoted to String here
}
After the null check, Dart knows text is a String in the rest of the function.

Promotion works on local variables and parameters. It does not work on class fields that could change between the check and the use; copy the field into a local variable first (final t = this.title; if (t != null) ...).

late and required

dart
class Profile {
  final String name;
  final String? bio;
  late final String initials;      // set later, but before use

  Profile({required this.name, this.bio}) {
    initials = name.split(' ').map((w) => w[0]).join();
  }
}
required forces callers to pass name; bio is optional and nullable; late promises initials will be set.

If you read a late variable before it is set, Dart throws a LateInitializationError. Use late only when you are sure about the order, for example values set in initState in Flutter (module 4).

Think of it like this: A nullable type is like a parcel marked "may be empty". ?. means "open it only if something is inside"; ?? means "if empty, use the spare"; ! means "rip it open and assume something is there", which hurts when the box is empty.

Common errors and fixes

  • "The argument type 'String?' can't be assigned to the parameter type 'String'": handle the null first (?? default, or a null check), do not just add !.
  • "Non-nullable instance field must be initialized": give it a value in the constructor, make it nullable, or (carefully) late.
  • "Null check operator used on a null value" at run time: an ! was wrong. Replace it with proper handling.
  • Making everything nullable "to be safe": then every use needs checks. Use non-null types wherever a value must exist.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Sound null safety · 1/6

String vs String?

In Dart three, null safety is always on. A String can never be null; a String with a question mark can.

Prefer a video by a teacher? Find free videos on “dart null safety explained late required null aware operators” on YouTube ↗

In real life: Showing a user's optional details

A job portal profile has a required name and optional company, city and photo URL. The model makes the optional ones nullable, and the profile screen shows company ?? 'Fresher' and city ?? 'Location not shared'. No screen can crash because a user skipped a field.

dart
class JobSeeker {
  final String name;
  final String? company;
  final String? city;
  JobSeeker({required this.name, this.company, this.city});
}

void main() {
  final p = JobSeeker(name: 'Imran');
  print('${p.name}, ${p.company ?? 'Fresher'}, ${p.city ?? 'Location not shared'}');
}
Prints: Imran, Fresher, Location not shared

Practice (0/3 done)

Task 1 · Question

What does this print? String? a; final b = a?.length ?? -1; print(b);

Task 2 · Question

Which line does NOT compile?

Task 3 · Practice

Write String displayPhone(String? input) that returns "Not given" for null or blank input, otherwise "+91 " plus the trimmed number. Use ?. and ?? (and isEmpty). Test with null, " " and " 9876543210 ". Make sure there is no ! anywhere.

Quick quiz

Question 1

1.What does int? mean?

Question 2

2.What does x ??= 5 do?

Question 3

3.When does Dart throw a LateInitializationError?

Question 4

4.What is "sound" null safety?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does int? mean?

Answer: An int that may also be null

The ? makes a type nullable.

What does x ??= 5 do?

Answer: Sets x to 5 only if x is null

Null-aware assignment.

When does Dart throw a LateInitializationError?

Answer: When a late variable is read before being set

late is a promise you must keep.

What is "sound" null safety?

Answer: If a type is non-nullable, the value can never be null at run time

The guarantee is enforced by the compiler.

With nullable reference types enabled, what does string? mean?Related

Answer: A string that may be null

The ? marks that null is an allowed value.

From null, nullable types and null-safe operators

What does x ?: 0 return when x is null?Related

Answer: 0

Elvis returns the right side when the left is null.

From Null safety

Which Dart 3 feature makes a switch over UI states exhaustive?Related

Answer: Sealed classes

All subtypes are known.

From Interview questions: Dart

In a Dart 3 switch expression, what does _ mean?Related

Answer: Match anything else (default)

The wildcard pattern.

From Control flow and collections

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Null safety and object-oriented Dart” before its exam: Classes and constructors, Inheritance, interfaces, mixins and extensions, Dart 3: enums, records, patterns and sealed classes.
  2. Module 2 exam: Null safety and object-oriented Dart · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Async Dart and packages. 50 topics left in the course before the final exam.

← Previous: Functions