ZetCode

Dart Null Value

last modified June 4, 2025

In Dart, null represents the absence of a value. It is a special value that indicates a variable has not been assigned any object reference.

With null safety introduced in Dart 2.12, variables cannot contain null by default. To allow null values, we must explicitly declare them as nullable.

Basic Null Concepts

Dart's type system distinguishes between nullable and non-nullable types. The ? suffix indicates a nullable type. The ! operator asserts a value is non-null.

Null-aware operators help safely work with potentially null values. These include ??, ?., and ??=. They provide concise ways to handle null cases.

Understanding null is crucial for writing robust Dart code. Proper null handling prevents runtime null reference exceptions and makes code more predictable.

Nullable vs Non-nullable Types

Dart 2.12+ enforces null safety by default. Variables cannot be null unless explicitly declared as nullable with the ? type suffix.

main.dart
void main() {
  // Non-nullable variable
  String name = 'Alice';
  // name = null; // Compile-time error
  
  // Nullable variable
  String? nullableName = 'Bob';
  nullableName = null; // Allowed
  
  print('Name: $name');
  print('Nullable name: $nullableName');
}

The first variable cannot be null, while the second can. Attempting to assign null to a non-nullable variable causes a compile-time error.

$ dart main.dart
Name: Alice
Nullable name: null

Null Assertion Operator

The ! operator asserts that an expression is non-null. Use it when you're sure a nullable variable contains a non-null value.

main.dart
void main() {
  String? maybeName = 'Alice';
  
  // Without assertion
  print('Length: ${maybeName?.length}');
  
  // With assertion
  print('Length: ${maybeName!.length}');
  
  maybeName = null;
  // print('Length: ${maybeName!.length}'); // Runtime error
}

The first print uses safe navigation (?.). The second asserts non-null with !. The commented line would throw a runtime exception if uncommented.

$ dart main.dart
Length: 5
Length: 5

Null-aware Operators

Dart provides several operators for concise null handling. The ?? operator provides a default value when null is encountered.

main.dart
void main() {
  String? name;
  
  // Null coalescing operator
  String displayName = name ?? 'Guest';
  print('Welcome, $displayName!');
  
  // Null-aware assignment
  name ??= 'Anonymous';
  print('Hello, $name!');
  
  // Null-aware access
  print('Name length: ${name?.length}');
}

The ?? operator provides 'Guest' when name is null. The ??= operator only assigns if the variable is null. The ?. operator safely accesses properties.

$ dart main.dart
Welcome, Guest!
Hello, Anonymous!
Name length: 9

Null Safety in Collections

Collections in Dart can contain null values unless explicitly restricted. We can specify whether list elements or map values can be null.

main.dart
void main() {
  // List with nullable elements
  List<int?> nullableNumbers = [1, null, 3];
  print('Nullable numbers: $nullableNumbers');
  
  // Map with nullable values
  Map<String, String?> userData = {
    'name': 'Alice',
    'email': null
  };
  print('User data: $userData');
  
  // Non-nullable list
  List<int> numbers = [1, 2, 3];
  // numbers.add(null); // Error
}

The first list and map allow null values. The last list prohibits nulls. The type system enforces these constraints at compile time.

$ dart main.dart
Nullable numbers: [1, null, 3]
User data: {name: Alice, email: null}

Optional Parameters and Null

Dart functions can have optional parameters that default to null. Named parameters are optional by default, while positional ones need [].

main.dart
void greet(String name, [String? title]) {
  print('Hello ${title != null ? '$title ' : ''}$name');
}

void printUser({String name = 'Guest', int? age}) {
  print('Name: $name, Age: ${age ?? 'unknown'}');
}

void main() {
  greet('Alice'); // No title
  greet('Bob', 'Dr.'); // With title
  
  printUser(); // Default name
  printUser(name: 'Charlie', age: 30); // All parameters
}

The greet function has an optional positional parameter. printUser uses named parameters with defaults. Both demonstrate null handling patterns.

$ dart main.dart
Hello Alice
Hello Dr. Bob
Name: Guest, Age: unknown
Name: Charlie, Age: 30

Best Practices

Source

Dart Null Safety Documentation

This tutorial covered Dart's null value with practical examples demonstrating null safety features and patterns.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.