Kode yang padat perhitungan sering menulis Math.sqrt, Math.pow, Math.abs berulang-ulang sampai awalan Math. muncul di hampir setiap baris. Java sejak versi 5 memberi jalan pintas resmi untuk situasi seperti itu: static import, fasilitas yang mengimpor member static — method dan konstanta — sehingga bisa dipakai tanpa menyebut nama class-nya. Fitur ini sederhana, tetapi punya batas jelas kapan ia membantu dan kapan justru menurunkan keterbacaan. Pada Chapter ini kita akan memakainya pada kode geometri, mengimpornya untuk konstanta, lalu melihat contoh konflik yang membuat compiler menolak kode.
Bentuk dan Mekanisme Static Import #
Seperti import biasa, static import ditulis setelah deklarasi package dan sebelum deklarasi class. Dua bentuknya sejajar dengan import class:
import static java.lang.Math.sqrt; // single-static: satu anggota
import static java.lang.Math.*; // static-on-demand: seluruh anggota MathMekanismenya sama dengan import biasa: compiler javac memetakan nama sederhana ke anggota aslinya saat resolusi nama — bytecode hasil kompilasi tetap mereferensikan java.lang.Math.sqrt. Static import tidak mengubah level akses sedikit pun: anggota private tetap tidak bisa diimpor, dan yang biasa tidak terlihat dari package kita tetap tidak bisa diimpor meski ditulis dalam import. Yang berubah hanya cara kita menuliskannya.
Satu penegasan penting: static import menyasar type (class atau interface), lalu mengambil anggota static-nya. Karena Math, Integer, dan System semuanya class dari java.lang, ketiganya adalah kandidat populer. Anggota non-static — method instance dan field per objek — tidak bisa diimpor dengan cara ini.
Kode Matematis yang Lebih Ringkas #
Program berikut menghitung sisi miring beberapa segitiga siku-siku dengan teorema Pythagoras. Perhatikan bahwa sqrt dan pow dipakai telanjang tanpa awalan Math.:
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
public class HitungSisiMiring {
public static void main(String[] args) {
double[][] segitiga = {
{3, 4},
{5, 12},
{8, 15}
};
for (double[] sisi : segitiga) {
double miring = sqrt(pow(sisi[0], 2) + pow(sisi[1], 2));
System.out.printf("sisi %.0f dan %.0f -> miring %.4f%n",
sisi[0], sisi[1], miring);
}
}
}Output yang Dihasilkan:
sisi 3 dan 4 -> miring 5.0000
sisi 5 dan 12 -> miring 13.0000
sisi 8 dan 15 -> miring 17.0000Mari kita telaah baris-baris kuncinya:
- Baris 1-2 (
import static java.lang.Math.pow;danimport static java.lang.Math.sqrt;): dua single-static import — sejak sini namasqrtdanpowdi berkas ini merujuk method static milikjava.lang.Math. - Baris 13 (
double miring = sqrt(pow(sisi[0], 2) + pow(sisi[1], 2));): rumus Pythagoras terbaca seperti notasi matematis di buku pelajaran. Bandingkan versi tanpa import:Math.sqrt(Math.pow(sisi[0], 2) + Math.pow(sisi[1], 2))— makna sama, derau lebih panjang. - Baris 14-15 (
System.out.printf(...)):printftetap dipanggil lewatSystem.outbiasa — static import kita memang hanya menyasarsqrtdanpow, bukan seluruh classMathatau fieldout.
Contoh kedua memakai static import untuk konstanta dan untuk System.out — dua pemakaian paling umum di kode nyata:
import static java.lang.Integer.MAX_VALUE;
import static java.lang.System.out;
public class BatasNilai {
public static void main(String[] args) {
out.println("MAX_VALUE int : " + MAX_VALUE);
out.println("Integer.MIN_VALUE + MAX_VALUE : " + (Integer.MIN_VALUE + MAX_VALUE));
out.println("luapan saat ditambah 1 : " + (MAX_VALUE + 1));
}
}Output yang Dihasilkan:
MAX_VALUE int : 2147483647
Integer.MIN_VALUE + MAX_VALUE : -1
luapan saat ditambah 1 : -2147483648Baris import static java.lang.System.out; mengimpor field out milik class System, sehingga out.println menggantikan System.out.println. Baris terakhir output juga mengingatkan kita pada luapan integer: MAX_VALUE + 1 melipat nilai ke batas bawah tanpa peringatan apa pun.
Ketika Keterbacaan Menurun #
Static import mulai merugikan begitu asal nama tidak lagi jelas. Bentuk paling ringan: pembaca bertanya “sqrt ini method siapa?” karena daftar import jauh di atas berkas. Bentuk yang lebih tegas ditolak compiler — ketika dua import menyasar nama sama:
import static java.lang.Integer.MAX_VALUE;
import static java.lang.Long.MAX_VALUE;
public class KonflikStatic {
public static void main(String[] args) {
System.out.println(MAX_VALUE);
}
}Compiler berhenti dengan pesan yang kita verifikasi langsung:
KonflikStatic.java:6: error: reference to MAX_VALUE is ambiguous
System.out.println(MAX_VALUE);
^
both variable MAX_VALUE in Integer and variable MAX_VALUE in Long matchNama MAX_VALUE ada di Integer (2147483647) dan di Long (9223372036854775807) dengan nilai berbeda — compiler menolak menebak dan memaksa kita memilih: hapus salah satu import, atau tulis Integer.MAX_VALUE secara eksplisit. Kasus ini sekaligus menunjukkan bahaya tersembunyi nama generik: MAX_VALUE, SIZE, EMPTY mudah bertabrakan antar class.
Satu anti-pola terakhir yang layak disebut: constant interface — interface yang berisi konstanta lalu diimpor static hanya demi menulis nama pendek. Interface semacam itu membocorkan detail implementasi ke API publik dan menyulitkan evolusi. Konstanta milik class utilitas yang tepat, misalnya java.util.concurrent.TimeUnit, jauh lebih sehat diimpor daripada dikandangkan dalam interface kosong.
Dengan import statik maupun biasa, kita kini bisa merujuk kode lintas package dengan nyaman. Saat proyek tumbuh, ratusan berkas .class di direktori build perlu dibungkus agar mudah dibagikan — dan itulah pekerjaan berkas JAR pada Chapter berikutnya.
Referensi #
- JLS SE25 §7.5.3: Single-Static-Import Declarations
- JLS SE25 §7.5.4: Static-Import-on-Demand Declarations
- Java API: java.lang.Math
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
BatasNilai.java
Unduh berkasimport static java.lang.Integer.MAX_VALUE;
import static java.lang.System.out;
public class BatasNilai {
public static void main(String[] args) {
out.println("MAX_VALUE int : " + MAX_VALUE);
out.println("Integer.MIN_VALUE + MAX_VALUE : " + (Integer.MIN_VALUE + MAX_VALUE));
out.println("luapan saat ditambah 1 : " + (MAX_VALUE + 1));
}
}
HitungSisiMiring.java
Unduh berkasimport static java.lang.Math.pow;
import static java.lang.Math.sqrt;
public class HitungSisiMiring {
public static void main(String[] args) {
double[][] segitiga = {
{3, 4},
{5, 12},
{8, 15}
};
for (double[] sisi : segitiga) {
double miring = sqrt(pow(sisi[0], 2) + pow(sisi[1], 2));
System.out.printf("sisi %.0f dan %.0f -> miring %.4f%n",
sisi[0], sisi[1], miring);
}
}
}
KonflikStatic.java
Unduh berkasimport static java.lang.Integer.MAX_VALUE;
import static java.lang.Long.MAX_VALUE;
public class KonflikStatic {
public static void main(String[] args) {
System.out.println(MAX_VALUE);
}
}