Kita sudah bisa mendeklarasikan variabel, tetapi Java menyediakan lebih dari satu cara melakukannya — ada deklarasi yang langsung diisi, ada yang ditunda, bahkan ada yang mengumpanyulkan beberapa nama dalam satu statement. Di balik variasi tersebut, compiler javac menjalankan analisis ketat bernama definite assignment: setiap variabel lokal harus terbukti sudah berisi nilai sebelum dipakai. Pada Chapter ini kita susun seluruh pola deklarasi dan inisialisasi, lalu menguji apa yang terjadi bila aturan tersebut dilanggar.
Empat Pola Deklarasi #
Dalam praktik sehari-hari, deklarasi variabel lokal muncul dalam empat pola:
- Deklarasi lalu assignment terpisah:
int stok;diikutistok = 40;— cocok saat nilai awal baru diketahui beberapa baris kemudian, misalnya setelah membaca masukan pengguna. - Deklarasi dengan inisialisasi langsung:
int terjual = 12;— pola tersering dan paling disarankan karena nilai variabel tidak pernah menggantung kosong. - Inisialisasi dari ekspresi:
int sisa = stok - terjual;— sisi kanan=boleh berupa ekspresi apa pun yang tipenya sesuai, termasuk pemanggilan method. - Banyak nama dalam satu statement:
int porsiA = 5, porsiB = 8;— satu tipe untuk beberapa nama, dipisah koma. Praktis untuk variabel berkerabat, tetapi jangan berlebihan hingga satu baris memuat puluhan nama.
Empat Pola dalam Satu Program #
Program berikut mempraktikkan keempat pola tersebut dalam alur tokot sederhana:
public class BentukDeklarasi {
public static void main(String[] args) {
int stok; // 1) deklarasi dulu, tanpa nilai
stok = 40; // lalu assignment terpisah
int terjual = 12; // 2) deklarasi + inisialisasi sekaligus
int sisa = stok - terjual; // 3) inisialisasi dari ekspresi
int porsiA = 5, porsiB = 8, total = porsiA + porsiB; // 4) banyak nama
String label = "Sisa stok hari ini: " + sisa;
System.out.println("stok = " + stok);
System.out.println("terjual = " + terjual);
System.out.println("sisa = " + sisa);
System.out.println("total = " + total);
System.out.println(label);
}
}Output yang Dihasilkan:
stok = 40
terjual = 12
sisa = 28
total = 13
Sisa stok hari ini: 28Mari kita bedah baris-baris kuncinya:
- Baris 3-4 (
int stok;lalustok = 40;): antara deklarasi dan assignment, variabelstokdikenal compiler tetapi tidak boleh dipakai. Setelah baris ke-4,stokresmi berisi40. - Baris 8 (
int sisa = stok - terjual;): sisi kanan dievaluasi memakai nilai dua variabel sebelumnya (40 - 12 = 28), lalu hasilnya menjadi nilai awalsisa. Urutan baris penting —stokdanterjualharus sudah berisi nilai pada saat baris ini dieksekusi. - Baris 10 (
int porsiA = 5, porsiB = 8, total = porsiA + porsiB;): tiga nama bertipeintdalam satu statement. Perhatikan bahwatotalboleh memakaiporsiAdanporsiBkarena kedua nama tersebut sudah diinisialisasi pada klausa sebelumnya dalam statement yang sama. - Baris 12 (
String label = ...): inisialisasi juga boleh menggabungkan teks — operator+antaraStringdan angka menghasilkanStringbaru.
Definite Assignment #
Compiler Java tidak hanya memeriksa tipe — compiler juga menelusuri alur program untuk memastikan setiap variabel lokal sudah pasti berisi nilai saat dibaca. Analisis ini bernama definite assignment (JLS §16). Konsekuensinya menarik: variabel boleh dideklarasikan dulu dan diisi di dalam percabangan, asalkan semua jalur menuju titik pembacaan mengisi variabel tersebut.
Program berikut menunda inisialisasi kategori ke dalam blok if/else, lalu mengakumulasi nilai total di dalam loop:
public class InisialisasiBersyarat {
public static void main(String[] args) {
int umur = 17;
String kategori;
if (umur >= 17) {
kategori = "dewasa";
} else {
kategori = "anak";
}
System.out.println("kategori = " + kategori);
int total = 0;
for (int i = 1; i <= 5; i++) {
total += i; // inisialisasi berangsur di dalam loop
}
System.out.println("total = " + total);
}
}Output yang Dihasilkan:
kategori = dewasa
total = 15Dua mekanisme menonjol di sini:
- Baris 4 dan 6-10 (
kategori):kategoridideklarasikan kosong, lalu diisi di kedua cabangif/else. Compiler menerima pola ini karena jalur manapun yang diambil — kondisi benar atau salah — variabelkategoripasti terisi sebelum baris 11 membacanya. - Baris 14-17 (
totaldantotal += i): variabel akumulator diinisialisasi0lebih dulu, lalu nilainya bertambah setiap putaran loop. Tanpa inisialisasitotal = 0di awal, statementtotal += iakan ditolak compiler karena membaca nilai yang belum ada.
Variabel Lokal yang Dipakai Tanpa Inisialisasi #
Bentuk pelanggaran paling sederhana: variabel dideklarasikan lalu langsung dibaca. Berkas berikut sengaja memuat kesalahan tersebut:
public class LupaInisialisasi {
public static void main(String[] args) {
int skor;
System.out.println(skor);
}
}Compiler javac menolak berkas tersebut dengan pesan error: variable skor might not have been initialized yang menunjuk ke pemakaian skor pada baris println. Perhatikan asimetri yang sudah kita bahas pada Chapter Reference Types: variabel lokal wajib diinisialisasi secara eksplisit, sedangkan field di dalam objek mendapat nilai bawaan otomatis (0, false, null). Asimetri ini disengaja — field hidup di objek yang diurus JVM, sementara variabel lokal di stack frame tidak dibersihkan dan tidak diinisialisasi JVM, sehingga compiler memaksa kita menulis nilai awal secara eksplisit.
Empat pola deklarasi di atas menuntut kita mengetik tipe secara eksplisit — int, String, double — bahkan ketika tipenya sudah jelas terbaca dari nilai inisialisasinya. Sejak Java 10, compiler dapat menyimpulkan tipe tersebut untuk kita lewat kata kunci var. Chapter berikutnya, Type Inference dengan var, membahas kapan fasilitas ini mempermudah dan kapan fasilitas ini justru dilarang dipakai.
Referensi #
- JLS SE25 §14.4: Local Variable Declarations
- JLS SE25 §16: Definite Assignment
- Oracle: Variables in Java
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
BentukDeklarasi.java
Unduh berkaspublic class BentukDeklarasi {
public static void main(String[] args) {
int stok; // 1) deklarasi dulu, tanpa nilai
stok = 40; // lalu assignment terpisah
int terjual = 12; // 2) deklarasi + inisialisasi sekaligus
int sisa = stok - terjual; // 3) inisialisasi dari ekspresi
int porsiA = 5, porsiB = 8, total = porsiA + porsiB; // 4) banyak nama
String label = "Sisa stok hari ini: " + sisa;
System.out.println("stok = " + stok);
System.out.println("terjual = " + terjual);
System.out.println("sisa = " + sisa);
System.out.println("total = " + total);
System.out.println(label);
}
}
InisialisasiBersyarat.java
Unduh berkaspublic class InisialisasiBersyarat {
public static void main(String[] args) {
int umur = 17;
String kategori;
if (umur >= 17) {
kategori = "dewasa";
} else {
kategori = "anak";
}
System.out.println("kategori = " + kategori);
int total = 0;
for (int i = 1; i <= 5; i++) {
total += i; // inisialisasi berangsur di dalam loop
}
System.out.println("total = " + total);
}
}
LupaInisialisasi.java
Unduh berkaspublic class LupaInisialisasi {
public static void main(String[] args) {
int skor;
System.out.println(skor);
}
}