Null Safety

Tipe nullable (?), operator ?., ??, ??=, !, late, pengecekan null dan promosi tipe, serta cara menulis kode bebas NullPointer.

Part 8 dari 20 ± 45 menit Gratis

Masalah "miliaran dolar"

Penemu konsep null menyebutnya "kesalahan miliaran dolar": program crash karena memakai nilai yang ternyata kosong. Dart menyelesaikannya dengan sound null safety: compiler menolak kode yang berpotensi memakai null secara keliru.

Aturan dasarnya

String nama = 'Budi';
// nama = null;        // ERROR: String tidak boleh null

String? alias = 'Bud';  // tanda ? = boleh null
alias = null;           // OK

Tipe tanpa ? tidak pernah null. Tipe dengan ? boleh null, dan Dart memaksamu menanganinya sebelum dipakai.

String? alias;
// print(alias.length);   // ERROR: alias mungkin null

Cara menangani nullable

OperatorArtiContoh
?.Akses aman; hasilnya null bila objek nullalias?.length
??Nilai cadangan bila nullalias ?? 'Tamu'
??=Isi hanya bila masih nullalias ??= 'Tamu'
!"Aku yakin ini tidak null" (berbahaya)alias!.length
?[ ]Indeks amandaftar?[0]
...?Spread aman[...?lain]
String? alias;
print(alias?.length);              // null (tidak crash)
print(alias ?? 'Tamu');            // Tamu
print(alias?.toUpperCase() ?? '-'); // -

Pengecekan null dan type promotion

Setelah kamu memeriksa null dengan if, Dart tahu variabel itu aman di dalam blok:

void cetak(String? teks) {
  if (teks == null) {
    print('kosong');
    return;
  }
  print(teks.length);      // OK: di sini teks pasti String
}

// Pola if-case (Dart 3)
if (alias case final a?) {
  print(a.length);          // a bertipe String
}

Promosi tipe hanya bekerja untuk variabel lokal dan final. Untuk field class, salin dulu ke variabel lokal.

Operator ! — gunakan dengan hemat

String? x = ambilNama();
print(x!.length);      // crash dengan error jika x ternyata null

! memindahkan pemeriksaan dari compiler ke waktu program jalan. Lebih baik pakai ?? atau if. Gunakan ! hanya jika logika menjamin nilainya ada.

late: diisi nanti

late String judul;           // non-null, tapi diisi setelah deklarasi
void muat() {
  judul = 'Dart';
}

late final String config = bacaKonfigurasi();   // late + inisialisasi malas:
                                                // dihitung hanya saat pertama dipakai

Jika late dibaca sebelum diisi, terjadi LateInitializationError.

required dan null

class Pengguna {
  final String nama;       // wajib ada
  final String? email;     // opsional

  Pengguna({required this.nama, this.email});
}

Pola ini menjadikan data wajib dan opsional terlihat jelas dari tipenya.

Nullable di collection

List<int?> a = [1, null, 3];       // elemen boleh null
List<int>? b;                       // listnya yang boleh null
Map<String, int> stok = {'a': 1};
int jumlah = stok['b'] ?? 0;        // hasil lookup Map selalu nullable

Ringkasan kebiasaan baik

  • Jadikan tipe non-null sebagai default; pakai ? hanya bila "tidak ada nilai" memang masuk akal.
  • Selesaikan null sedini mungkin dengan ?? atau return awal.
  • Hindari ! dan dynamic.

Error umum

  • The property 'length' can't be unconditionally accessed because the receiver can be 'null'. → gunakan ?. atau cek null dulu.
  • Null check operator used on a null value → ! dipakai pada nilai null.
  • LateInitializationError → variabel late dibaca sebelum diisi.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X