Belajar Dart - Null Safety & Type System
Episode 6 of 23

Belajar Dart - Null Safety & Type System

Episode ini membedah sistem tipe dan null safety Dart: perbedaan nullable dan non-nullable, operator ?. dan ??, inisialisasi late, type promotion, serta cara kerja sound null safety dan tool migrasi.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Null-reference error — yang oleh Tony Hoare disebut sebagai billion dollar mistake — adalah sumber bug paling umum di banyak bahasa. Dart menjawabnya dengan sound null safety: sistem tipe membedakan secara tegas nilai yang boleh null dan yang tidak boleh null, dan kompiler menegakkannya sejak waktu kompilasi.

Episode 6 membedah mekanisme ini secara menyeluruh. Kalian akan belajar menandai tipe nullable dengan tanda tanya, memakai operator null-aware, memahami late, memanfaatkan type promotion, serta mengikuti alur migrasi kode lama.

Dengan null safety yang sound, sebagian besar kategori bug hilang bahkan sebelum program dijalankan.

Nullable vs Non-Nullable Types

Tanda Tanya untuk Nullable

Secara default, tipe di Dart bersifat non-nullable. Untuk mengizinkan null, tambahkan tanda tanya:

Nullable dan non-nullable
void main() {
  String nama = 'Dart';       // tidak boleh null
  String? namaOpsional;       // boleh null
 
  namaOpsional = null;        // valid
  print(namaOpsional);
}

String? namaOpsional menandakan bahwa nilai bisa null atau String. Kompiler akan menolak kode yang memakai variabel nullable tanpa pemeriksaan, karena nilainya belum tentu tersedia.

Operator Bang untuk Assert Non-null

Jika kalian yakin nilai nullable bukan null pada suatu titik, gunakan operator !:

Operator bang
void main() {
  String? hasil;
 
  hasil = 'selesai';
 
  if (hasil != null) {
    print(hasil.length);
  }
}

Di atas, blok if mempersempit tipe hasil dari nullable menjadi non-nullable — ini yang disebut type promotion. Gunakan ! hanya saat benar-benar yakin, karena pemaksaan yang salah tetap bisa menyebabkan runtime error.

Operator Null-Aware

Safe Navigation ?.

Akses properti dan method tanpa risiko error memakai ?.:

Safe navigation
void main() {
  String? nama;
  print(nama?.length);   // null, bukan error
  print(nama?.toUpperCase() ?? 'tidak ada');
}

nama?.length mengembalikan null ketika nama null, alih-alih melempar exception. Operator ini menghilangkan rantai pengecekan null yang panjang.

Null Coalescing ?? dan ??=

Operator ?? menyediakan nilai fallback, dan ??= meng-assign jika bernilai null:

Null-aware operators
void main() {
  String? konfigurasi;
 
  var nilai = konfigurasi ?? 'default';
  konfigurasi ??= 'diset sekali';
 
  print(nilai);
  print(konfigurasi);
}

konfigurasi ??= 'diset sekali' hanya meng-assign jika konfigurasi masih null. Kombinasi ?., ??, dan ??= membuat kode null-handling yang ekspresif dan aman.

Inisialisasi Late dan Type Promotion

late untuk Inisialisasi Tertunda

Terkadang field tidak bisa diisi di constructor, misalnya karena bergantung pada data yang baru tersedia nanti. Gunakan late:

Inisialisasi late
class Pengaturan {
  late String koneksi;
 
  void muat() {
    koneksi = 'redis://localhost:6379';
  }
}
 
void main() {
  var p = Pengaturan();
  p.muat();
  print(p.koneksi);
}

late String koneksi menunda inisialisasi hingga muat() dipanggil. Kompiler menjamin bahwa field late selalu diinisialisasi sebelum dibaca.

Type Promotion pada Variabel Lokal

Dart mempersempit tipe secara otomatis setelah pemeriksaan. Ini bekerja sangat baik untuk variabel lokal dan parameter private:

Type promotion
void proses(Object input) {
  if (input is String) {
    print(input.toUpperCase());
  } else if (input is int) {
    print(input + 1);
  }
}
 
void main() {
  proses('halo');
  proses(41);
}

Di dalam blok input is String, kompiler memperlakukan input sebagai String sehingga method toUpperCase tersedia tanpa cast manual. Promotion mengurangi kode boilerplate secara signifikan.

Sound Null Safety dan Tool Migrasi

Apa yang Dimaksud Sound

Sound berarti jaminan tipe berlaku di seluruh program, termasuk saat memakai library lama atau interop native. Kompiler dan runtime tidak akan menemukan null di tempat yang secara statis non-nullable. Konsekuensinya: lintasan optimasi lebih agresif dan app lebih kecil serta cepat.

Migrasi Kode Lama

Untuk project yang dibuat sebelum null safety (Dart di bawah 2.12), gunakan tool migrasi resmi:

Menjalankan tool migrasi
dart migrate

dart migrate menganalisis seluruh project dan menyusun perubahan tipe secara interaktif. Setelah selesai, pastikan constraint SDK di pubspec.yaml minimal sdk: ^2.12.0 dan jalankan dart analyze untuk memastikan tidak ada error.

Penutup

Inti yang harus dibawa pulang:

  • Tipe non-nullable tidak bisa menampung null; tambahkan ? untuk membuat nullable.
  • Operator ! memaksa nilai non-null hanya jika kalian yakin.
  • ?. mengakses tanpa error; ?? memberi fallback; ??= meng-assign jika null.
  • late menunda inisialisasi field; kompiler tetap menjamin keamanannya.
  • Type promotion mempersempit tipe otomatis setelah pemeriksaan is.
  • Migrasi project lama memakai dart migrate lalu cek dengan dart analyze.

Di episode 7 selanjutnya kita akan membahas asynchronous programming — penggunaan Future dengan async dan await, penanganan error, dasar Stream dengan listener dan transformasi, model Isolate untuk concurrency, serta use case asynchronous I/O di aplikasi nyata.

Belajar Dart - Null Safety & Type System | Belajar Dart