null-safetynullableMenengah6 mnt baca

Null Safety

Fitur paling terkenal Dart: tipe nullable, operator ?., ??, dan ! untuk kode bebas null error.

Masalah miliaran dolar

Tony Hoare, penemu referensi null, menyebutnya "kesalahan miliaran dolar": hampir semua bahasa membiarkan variabel berisi null tanpa peringatan, lalu program crash saat null itu dipakai. Dart menyelesaikan ini dengan null safety: secara default, variabel tidak boleh null.

dart
void main() {
  String nama = 'Rizky';
  // nama = null; // ERROR: String tidak boleh null

  String? panggilan; // tanda ? berarti BOLEH null
  print(panggilan); // null, tidak error
}

Aturannya sederhana:

  • String = pasti ada isinya, tidak mungkin null
  • String? = boleh null, harus ditangani sebelum dipakai

Compiler melacak ini untukmu. Kode yang berpotensi null error ditolak sejak ditulis, bukan crash saat jalan.

Membaca nilai nullable dengan aman

Ada empat cara menghadapi String?:

dart
void main() {
  String? nama;

  // 1. Cek null dulu
  if (nama != null) {
    print(nama.length); // aman, compiler tahu nama tidak null di sini
  }

  // 2. Operator ?. (panggil hanya jika tidak null)
  print(nama?.length); // null, tidak crash

  // 3. Operator ?? (nilai cadangan)
  print(nama ?? 'Tamu'); // Tamu
  print(nama?.length ?? 0); // 0

  // 4. Operator ! (jaminan programmer) -- HATI-HATI
  // print(nama!.length); // CRASH! jangan lakukan ini
}

Cara 1-3 aman. Cara 4 (!) artinya "saya jamin tidak null, percaya saya". Kalau ternyata null, program crash. Pakai ! hanya saat kamu benar-benar yakin, mis. nilai sudah dicek di baris sebelumnya tapi compiler tidak bisa melihatnya.

Catatan teknis: ! adalah sumber crash paling umum di kode Flutter pemula. Aturan praktis: kalau kamu mengetik !, berhenti sejenak dan tanya "bisakah saya pakai ?? atau ?. saja?". Sembilan dari sepuluh kasus jawabannya ya. Crash null di production hampir selalu berasal dari ! yang terlalu percaya diri.

Null safety di parameter dan property

dart
class User {
  final String nama;      // wajib diisi, tidak boleh null
  final String? bio;      // opsional

  User({required this.nama, this.bio});

  String get tampilanBio => bio ?? 'Belum ada bio.';
}

void main() {
  var u = User(nama: 'Rizky');
  print(u.tampilanBio); // Belum ada bio.
}

Pola ini standar di Flutter: field wajib pakai required + tipe non-nullable, field opsional pakai ?.

Late: janji "nanti diisi" (preview)

Kadang variabel non-nullable belum bisa diisi saat deklarasi, tapi pasti terisi sebelum dipakai. Keyword late menunda pengecekan:

dart
late String sapaan;

void main() {
  sapaan = 'Halo!';
  print(sapaan); // aman
}

Tanpa late, compiler protes karena sapaan belum diisi. Dengan late, kamu berjanji akan mengisinya sebelum dipakai. Kalau ingkar, error LateInitializationError saat program jalan. Modul berikutnya membahas late lebih dalam.

Flow analysis: compiler yang pintar

Dart menganalisis alur kode untukmu:

dart
void main() {
  String? nama = 'Rizky';

  if (nama == null) {
    print('tidak ada nama');
  } else {
    print(nama.length); // OK tanpa ?. karena sudah dicek
  }
}

Setelah cek nama == null di cabang else, compiler tahu nama tidak null. Ini disebut promotion, dan bikin kode null-safe tetap enak dibaca tanpa operator di mana-mana.

Checklist null safety

  1. Default: pakai tipe non-nullable (String, bukan String?)
  2. Butuh null? Tambah ? dan tangani dengan ?., ??, atau cek != null
  3. Hindari ! kecuali benar-benar yakin
  4. Property non-nullable wajib diisi lewat constructor

Ikuti empat ini dan kamu sudah menulis kode yang lebih aman dari kebanyakan tutorial di internet.