Keyword late
Menunda inisialisasi dengan late: kapan berguna dan jebakan LateInitializationError.
Masalah yang diselesaikan late
Null safety menuntut variabel non-nullable langsung terisi. Tapi ada kasus wajar di mana nilainya belum tersedia saat deklarasi:
class Game {
late String pemain; // belum tahu siapa pemainnya saat object dibuat
void mulai(String nama) {
pemain = nama;
}
void tampil() {
print('Pemain: $pemain');
}
}
void main() {
var g = Game();
g.mulai('Rizky');
g.tampil();
}Tanpa late, pemain harus nullable (String?) atau diisi di constructor. Dengan late, kita bilang ke compiler: "tenang, saya yang tanggung jawab mengisinya sebelum dipakai".
LateInitializationError: janji yang ingkar
Kalau kamu lupa menepati janji, Dart menghukummu saat runtime:
late String data;
void main() {
print(data); // LateInitializationError: Field 'data' has not been initialized.
}Error ini tidak tertangkap saat compile, hanya muncul saat program jalan dan baris itu dieksekusi. Makanya late dikategorikan topik mahir: butuh disiplin.
Catatan teknis:
LateInitializationErroradalah salah satu error paling membingungkan buat pemula karena pesannya teknis dan munculnya tidak tentu. Kalau kamu melihatnya, artinya ada variabellateyang dibaca sebelum diisi. Telusuri alur program: pastikan setiap jalur eksekusi mengisi variabel itu dulu sebelum ada yang membacanya.
late final: isi sekali, tapi nanti
Kombinasi late final untuk nilai yang dihitung sekali secara malas:
class Config {
late final String token = _ambilToken();
String _ambilToken() {
print('Mengambil token...');
return 'abc123';
}
}
void main() {
var c = Config();
print('Object dibuat');
print(c.token); // 'Mengambil token...' baru dicetak DI SINI
print(c.token); // tidak dihitung ulang
}Fungsi _ambilToken() baru dipanggil saat token pertama kali dibaca, bukan saat object dibuat. Ini disebut lazy initialization: hemat kalau perhitungannya mahal dan belum tentu dibutuhkan.
Kapan pakai late (dan kapan tidak)
Cocok untuk late:
- Field yang diisi di
initState()pada Flutter (pola sangat umum) - Nilai mahal yang dihitung malas dengan
late final - Variabel top-level yang butuh setup dulu
Jangan pakai late kalau:
- Nilainya bisa diisi langsung (pakai final biasa)
- Bisa jadi tidak terisi (pakai nullable
?saja, lebih jujur) - Kamu tidak yakin alur pengisiannya (risiko LateInitializationError)
// Kurang baik: late + nullable = membingungkan, hindari
// late String? nama;
// Baik: jujur nullable
String? nama;
// Baik: late dengan alur jelas
late final String id;
void setup() {
id = 'user-123';
}Pola Flutter: late di State
Ini pola yang akan sering kamu lihat di Flutter:
// Ilustrasi pola (bukan kode Flutter asli):
class HalamanState {
late String judul;
void initState() {
judul = 'Beranda'; // diisi sekali saat inisialisasi
}
void build() {
print(judul); // aman dibaca setelah initState
}
}Framework menjamin initState() jalan sebelum build(), jadi late di sini aman. Tapi kalau kamu baca judul sebelum initState, tetap error. Pahami kontrak urutan eksekusi setiap kali pakai late.
Kesimpulan
late adalah alat tajam: menyelesaikan masalah inisialisasi tertunda dengan elegan, tapi menuntut kamu paham alur program. Kalau ragu, pilih nullable (?) yang jujur daripada late yang berisiko. Kode yang sedikit lebih verbose tapi tidak pernah crash selalu menang.