dartnull-safetydasarMahir5 mnt baca

Null Safety Dasar

Memahami null safety: kenapa null berbahaya dan cara Dart mengatasinya.

Mengakhiri mimpi buruk null

NullPointerException adalah error paling terkenal di dunia pemrograman, julukannya "kesalahan satu miliar dolar" karena miliaran jam debugging terbuang karenanya. Penyebabnya sederhana: kode memakai data yang ternyata kosong (null) tanpa mengecek dulu.

Null safety adalah jawaban Dart: sistem yang memaksa kamu menangani kemungkinan null sejak kode ditulis, bukan saat aplikasi crash di tangan pengguna.

Analogi: null safety itu seperti sabuk pengaman yang tidak bisa dilepas saat mobil jalan. Merepotkan di awal, tapi menyelamatkan nyawa (aplikasimu) nanti.

Kenapa null safety ada?

Sebelum null safety, variabel apa pun bisa null kapan saja, dan compiler diam saja. Error baru muncul saat runtime, di kondisi yang sulit direproduksi. Null safety membalik ini: compiler menjadi penjaga ketat yang menolak kode berisiko sejak awal.

Non-nullable vs nullable

Aturan intinya sederhana:

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

  String? panggilan; // ? artinya BOLEH null
  print(panggilan); // null, nilai default variabel nullable

  panggilan = 'Bang Budi';
  print(panggilan); // Bang Budi
}
  • String: non-nullable, dijamin tidak pernah null. Compiler menjaganya.
  • String?: nullable, boleh null. Kamu wajib menanganinya sebelum dipakai.

Contoh kedua, null safety menangkap bug sejak compile:

dart
void main() {
  String? nama;

  // print(nama.length); // ERROR COMPILE: nama bisa null!
  // Compiler berkata: "tanganimu dulu kemungkinan null-nya"

  // Cara 1: cek dulu
  if (nama != null) {
    print(nama.length); // OK: di sini compiler TAHU nama tidak null
  }

  // Cara 2: beri default
  print(nama?.length ?? 0); // 0, aman
}

Perhatikan keajaiban di Cara 1: setelah if (nama != null), compiler mempromosikan nama menjadi non-nullable di dalam blok. Ini disebut flow analysis, dan ia bekerja otomatis.

Kapan memakai nullable?

dart
class Pengguna {
  String nama; // wajib ada: non-nullable
  String? bio; // opsional: nullable, boleh kosong

  Pengguna(this.nama, [this.bio]);
}

void main() {
  var u1 = Pengguna('Budi');
  var u2 = Pengguna('Ani', 'Ngoding tiap hari');

  print('${u1.nama}: ${u1.bio ?? "belum ada bio"}');
  print('${u2.nama}: ${u2.bio}');
}

Aturan jempol: default-nya non-nullable. Tambahkan ? hanya untuk data yang memang boleh kosong secara konsep (bio opsional, hasil pencarian yang mungkin tidak ketemu).

Kesalahan umum

1. Menabur ? di mana-mana agar "aman"

dart
// SALAH: semua nullable = kamu bohong ke compiler
void main() {
  String? nama = 'Budi';
  int? umur = 17;
  // ...lalu pusing menangani null di mana-mana
}
dart
// BENAR: ? hanya untuk yang memang boleh kosong
void main() {
  String nama = 'Budi';
  int umur = 17;
  String? bio; // hanya ini yang opsional
}

Terlalu banyak ? justru menambah beban: setiap pemakaian butuh penanganan null.

2. Memakai ! untuk membungkam compiler

dart
// BERBAHAYA
void main() {
  String? nama;
  // print(nama!.length); // compile OK, tapi CRASH saat runtime!
}
dart
// BENAR
void main() {
  String? nama = 'Budi';
  if (nama != null) {
    print(nama.length); // aman, tanpa !
  }
}

Operator ! (null assertion) artinya "aku jamin tidak null". Kalau jaminanmu salah, aplikasi crash. Pakai hanya saat kamu benar-benar yakin, mis. setelah validasi yang tidak bisa dibaca compiler.

3. Lupa inisialisasi field non-nullable

dart
// SALAH
// class Siswa {
//   String nama; // ERROR: non-nullable harus diisi
// }
dart
// BENAR: tiga jalan keluar
class Siswa {
  String nama = ''; // 1. nilai default
}

class Siswa2 {
  String nama; // 2. via constructor
  Siswa2(this.nama);
}

class Siswa3 {
  late String nama; // 3. late: janji diisi sebelum dipakai
  void isi(String n) => nama = n;
}

Kata kunci late dibahas detail di modulnya sendiri.

Kesimpulan

Null safety = compiler sebagai penjaga null. Default non-nullable, ? hanya untuk yang memang boleh kosong, tangani dengan if != null atau ??, hindari ! kecuali yakin. Fitur ini adalah alasan utama Dart modern minim crash null.

Catatan teknis: Null safety Dart bersifat sound: jika kode lolos compile tanpa !, dijamin tidak ada null dereference saat runtime. Jaminan sekuat ini langka di bahasa mainstream.

Tantangan

Sambutan aman null

Buat fungsi sapa(String? nama) yang mencetak "Halo, {nama}!" jika nama tidak null, atau "Halo, tamu!" jika null. Jangan pakai !.

text
// TODO: fungsi sapa

void main() {
  // TODO: panggil dengan 'Rina' dan dengan null
}