Array tidak terbatas menyimpan angka — justru pemanfaatan paling umumnya adalah menampung sekumpulan objek: daftar siswa, katalog produk, atau antrean pesanan. Mekanismenya perlu dipahami dengan tepat: elemen array bertipe objek menyimpan referensi, bukan objeknya sendiri. Akibatnya ada dua langkah pembuatan — membuat array untuk menampung referensi, lalu membuat objek satu per satu untuk tiap slot. Chapter ini membedah kedua langkah tersebut beserta kesalahan NullPointerException yang muncul bila salah satu langkah terlewat.
Membuat Array Berisi Referensi #
Perhatikan perbedaan penting antara new Siswa[3] dan new Siswa(). Ekspresi pertama membuat array berisi tiga slot referensi yang seluruhnya diisi null — belum ada satu pun objek Siswa di dalamnya. Ekspresi kedua membuat satu objek Siswa di heap. Array berisi objek selalu membutuhkan dua tahap tersebut: slot disiapkan dulu, objek diisi kemudian.
Bentuk ringkasnya pun tersedia: array initializer bekerja untuk objek juga, misalnya Siswa[] kelas = {new Siswa("Budi", 85), new Siswa("Siti", 92)}; — compiler menghitung jumlah elemen dari jumlah ekspresi new di dalam kurung kurawal. Ukuran array tetap beku setelah dibuat; menambah siswa berarti membuat array baru dan menyalin isinya, persis mekanisme Chapter Array Copying.
import java.util.Arrays;
class Siswa {
String nama;
int nilai;
Siswa(String nama, int nilai) {
this.nama = nama;
this.nilai = nilai;
}
@Override
public String toString() {
return nama + "(" + nilai + ")";
}
}
public class ArrayObjek {
public static void main(String[] args) {
Siswa[] kelas = new Siswa[3];
System.out.println("Array baru : " + Arrays.toString(kelas));
kelas[0] = new Siswa("Budi", 85);
kelas[1] = new Siswa("Siti", 92);
kelas[2] = new Siswa("Dewi", 78);
System.out.println("Setelah diisi : " + Arrays.toString(kelas));
int total = 0;
for (Siswa s : kelas) {
total += s.nilai;
}
System.out.println("Rata-rata : " + (total / kelas.length));
}
}Output yang Dihasilkan:
Array baru : [null, null, null]
Setelah diisi : [Budi(85), Siti(92), Dewi(78)]
Rata-rata : 85Mari kita telaah baris-baris kode di atas:
- Baris 3-18 (class
Siswa): class sederhana dengan dua field, constructor, dantoStringyang menampilkan formatnama(nilai)— agarArrays.toStringmencetak isi yang berarti, bukan penanda internal objek. - Baris 22 (
Siswa[] kelas = new Siswa[3];): membuat array tiga slot referensi. Output “Array baru” menunjukkan[null, null, null]— belum ada objekSiswayang dibuat, hanya tempatnya yang tersedia. - Baris 26-28 (
kelas[0] = new Siswa("Budi", 85);dst.): tahap kedua — constructor dipanggil tiga kali, menghasilkan tiga objek terpisah di heap, lalu referensinya disimpan ke slot masing-masing. - Baris 31-33 (perulangan
for): variabelsberganti-ganti menampung referensi tiap elemen. Fields.nilaidibaca langsung dari objek yang dirujuk, menghasilkan total255dan rata-rata85.
Membaca Field dari Slot yang Masih null #
Kesalahan klasiknya: mengakses member objek pada slot yang belum diisi. Compiler javac tidak bisa menolak daftar[0].nama karena tipe daftar[0] memang Peserta dan field nama sah — baris kode tersebut lolos pemeriksaan kompilasi. Baru saat program berjalan, JVM menemukan referensi bernilai null dan melempar NullPointerException.
class Peserta {
String nama;
}
public class ObjekNull {
public static void main(String[] args) {
Peserta[] daftar = new Peserta[2];
System.out.println("Membaca daftar[0].nama...");
System.out.println(daftar[0].nama);
}
}Program di atas gagal dengan pesan persis berikut pada jalur keluar (exit code 1):
Exception in thread "main" java.lang.NullPointerException: Cannot read field "nama" because "<local1>[0]" is null
at ObjekNull.main(ObjekNull.java:9)Pesan tersebut menyebutkan persis apa yang terjadi: membaca field nama gagal karena elemen [0] dari array lokal bernilai null. Solusinya bukan menghindari array of objects, melainkan memastikan objek dibuat sebelum slotnya dipakai — isi dengan new per elemen seperti contoh pertama, atau periksa if (daftar[0] != null) bila memang ada slot yang sengaja kosong.
Perlu dicatat juga bahwa dua elemen array bisa menunjuk objek yang sama: kelas[1] = kelas[0] tidak menduplikasi objek Siswa, hanya menyamakan referensinya — pola referensi yang sama persis dengan Chapter Array Copying. Dengan bekal array dan objek ini, kita berpindah ke struktur data tekstual: String, tipe yang paling sering kita olah sehari-hari di Java.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
ArrayObjek.java
Unduh berkasimport java.util.Arrays;
class Siswa {
String nama;
int nilai;
Siswa(String nama, int nilai) {
this.nama = nama;
this.nilai = nilai;
}
@Override
public String toString() {
return nama + "(" + nilai + ")";
}
}
public class ArrayObjek {
public static void main(String[] args) {
Siswa[] kelas = new Siswa[3];
System.out.println("Array baru : " + Arrays.toString(kelas));
kelas[0] = new Siswa("Budi", 85);
kelas[1] = new Siswa("Siti", 92);
kelas[2] = new Siswa("Dewi", 78);
System.out.println("Setelah diisi : " + Arrays.toString(kelas));
int total = 0;
for (Siswa s : kelas) {
total += s.nilai;
}
System.out.println("Rata-rata : " + (total / kelas.length));
}
}
ObjekNull.java
Unduh berkasclass Peserta {
String nama;
}
public class ObjekNull {
public static void main(String[] args) {
Peserta[] daftar = new Peserta[2];
System.out.println("Membaca daftar[0].nama...");
System.out.println(daftar[0].nama);
}
}