Menulis String nama = "Budi"; terasa mengandung pengulangan — tipe String sudah jelas terbaca dari nilai inisialisasinya. Sejak Java 10, compiler dapat menyimpulkan tipe variabel lokal tersebut lewat kata kunci var: var nama = "Budi";. Penting dipahami sejak awal: var bukan tipe dinamis seperti di Python atau JavaScript. Java tetap statically typed — compiler mengganti var dengan tepat satu tipe hasil penyimpulan, dan tipe tersebut terkunci sejak kompilasi. Pada Chapter ini kita pelajari cara kerja, batasan, dan gaya pemakaian var yang sehat.
Cara Kerja var #
Ketika compiler javac menemui var umur = 17;, compiler melihat initializer di sisi kanan, menyimpulkan tipenya (int), lalu memperlakukan deklarasi tersebut persis seperti int umur = 17;. Hasil bytecode-nya identik — var adalah fasilitas murni level bahasa, bukan fitur runtime. Tiga konsekuensi langsung mengikuti mekanisme tersebut:
- Tipe terkunci setelah disimpulkan:
vartidak berubah-ubah. Variabelvar nama = "Budi";adalah variabelStringselamanya. - Initializer wajib: tanpa nilai awal, compiler tidak punya bahan penyimpulan.
var x;ditolak dengan pesancannot infer type for local variable x. - Null tidak bisa disimpulkan:
var x = null;gagal karenanulltidak memuat informasi tipe.
var dalam Praktik #
Program berikut memakai var untuk beragam tipe, termasuk List<String> hasil pabrik List.of — tempat tipe panjang seperti List<String> membuat var terasa paling berguna:
import java.util.List;
public class InferensiVar {
public static void main(String[] args) {
var nama = "Budi"; // String
var umur = 17; // int
var tinggi = 168.5; // double
var lulus = true; // boolean
var daftar = List.of("Budi", "Siti", "Dewi"); // List<String>
System.out.println("nama = " + nama);
System.out.println("umur = " + umur);
System.out.println("tinggi = " + tinggi);
System.out.println("lulus = " + lulus);
System.out.println("daftar = " + daftar);
umur = umur + 1; // boleh: int ke int
System.out.println("umur = " + umur);
for (var siswa : daftar) { // var juga sah di loop
System.out.println("siswa = " + siswa);
}
}
}Output yang Dihasilkan:
nama = Budi
umur = 17
tinggi = 168.5
lulus = true
daftar = [Budi, Siti, Dewi]
umur = 18
siswa = Budi
siswa = Siti
siswa = DewiMari kita bedah baris-baris kuncinya:
- Baris 5-9 (lima deklarasi
var): compiler menyimpulkanString,int,double,boolean, danList<String>dari masing-masing initializer. Perhatikan baris 9 —varmenghemat penulisanList<String> daftar = ...yang bertele-tele tanpa mengurangi kejelasan sedikit pun. - Baris 16 (
umur = umur + 1;): reassignment bertipe sama tetap sah. Variabelumursudah dikunci sebagaiintsejak baris 6, dan18adalah nilaiintyang cocok. - Baris 19 (
for (var siswa : daftar)):varjuga boleh dipakai sebagai variabel loop enhanced for. Compiler menyimpulkansiswabertipeStringkarenadaftaradalahList<String>.
var Bukan Tipe Dinamis #
Pembaca yang datang dari Python atau JavaScript kerap mengira var memungkinkan variabel berganti tipe. Program berikut menguji dugaan tersebut — dan gagal dikompilasi:
public class VarGantiTipe {
public static void main(String[] args) {
var nama = "Budi";
nama = 17;
System.out.println(nama);
}
}Compiler javac menolak dengan pesan error: incompatible types: int cannot be converted to String. Pesan tersebut membuktikan bahwa variabel nama memang telah menjadi variabel String — bukan wadah serbaguna. Penyimpulan terjadi sekali di baris deklarasi; setelah itu seluruh aturan tipe Java berlaku penuh seperti biasa.
Batasan var #
var hanya berlaku untuk variabel lokal di dalam method, constructor, atau blok inisialisasi. Tiga lokasi berikut menolak var:
- Field class: tidak ada jaminan urutan inisialisasi yang bisa dianalisis compiler, jadi tipe field harus ditulis eksplisit.
- Parameter method: tanda tangan method adalah kontrak publik yang harus terbaca tanpa melihat isi method.
- Tipe kembalian method: alasan sama dengan parameter — kontrak publik.
Berkas berikut mencoba memakai var sebagai field dan langsung ditolak:
public class VarDilarangField {
var nama = "Budi";
public static void main(String[] args) {
System.out.println("program ini memang gagal dikompilasi");
}
}Pesan compiler-nya tegas: error: 'var' is not allowed here, menunjuk ke baris deklarasi field. Selain tiga lokasi tersebut, var juga tidak bisa dipakai untuk deklarasi tanpa initializer, untuk var x = null;, serta sebagai nama tipe array seperti var[] x.
Dengan var, tipe yang panjang tidak lagi membebani penulisan, dan compiler tetap menjaga kontrak tipe secara penuh. Sejauh ini seluruh variabel kita boleh berubah nilainya kapan saja. Bagaimana jika kita justru ingin nilai yang terkunci — misalnya batas maksimum yang tidak boleh diubah siapa pun? Java menyediakan modifier final, yang menjadi fokus Chapter berikutnya.
Referensi #
- JLS SE25 §14.4: Local Variable Declarations
- JEP 286: Local-Variable Type Inference
- Oracle: Local Variable Type Inference
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
InferensiVar.java
Unduh berkasimport java.util.List;
public class InferensiVar {
public static void main(String[] args) {
var nama = "Budi"; // String
var umur = 17; // int
var tinggi = 168.5; // double
var lulus = true; // boolean
var daftar = List.of("Budi", "Siti", "Dewi"); // List<String>
System.out.println("nama = " + nama);
System.out.println("umur = " + umur);
System.out.println("tinggi = " + tinggi);
System.out.println("lulus = " + lulus);
System.out.println("daftar = " + daftar);
umur = umur + 1; // boleh: int ke int
System.out.println("umur = " + umur);
for (var siswa : daftar) { // var juga sah di loop
System.out.println("siswa = " + siswa);
}
}
}
VarDilarangField.java
Unduh berkaspublic class VarDilarangField {
var nama = "Budi";
public static void main(String[] args) {
System.out.println("program ini memang gagal dikompilasi");
}
}
VarGantiTipe.java
Unduh berkaspublic class VarGantiTipe {
public static void main(String[] args) {
var nama = "Budi";
nama = 17;
System.out.println(nama);
}
}