Sunday, March 2, 2008

Java 5 : Apa itu Generic ?

Generic diperkenalkan pada Java versi 5. Apa sebenarnya generic itu ? Kenapa sampai diperlukan generic ? Berikut saya akan coba uraikan latar belakang dan cara penggunaan generic ini.

Latar Belakang

Generic dikenal juga sebagai tipe data berparameter (parameterized types), yaitu tipe data yang biasanya didefinisikan di bagian argumen/parameter dan bersifat generik atau dikenali pada saat runtime.

Jika kita memiliki data untype (bertipe Object), maka biasanya kita melakukan casting untuk mengambil nilainya. Kesalahan konversi tipe data ini pada saat runtime sangat mungkin dan sering sekali terjadi. Untuk menghindarinya inilah kita perlu menempatkan tipe data generic ini.

Mari kita buat satu contoh konkret....

ArrayList adalah sebuah class yang sangat berguna dan merupakan bagian dari tipe data Collection. ArrayList bisa menampung data dalam bentuk list dengan Object sebagai nilainya.

Dengan demikian, input atau masukan nilai ke objek bertipe ArrayList ini sangatlah flexible karena seperti yang kita tahu, semua class di Java pasti diturunkan dari class Object.

Pada contoh class BeforeGeneric1 di bawah ini, objek arrList bertipe ArrayList dan dapat menerima 3 input. Kita beri nilai masing-masing 10, new Integer(100), dan "Hello World".

Ketiganya adalah tipe data yang berbeda satu sama lain tetapi valid.



import java.util.ArrayList;
import java.util.List;

public class BeforeGeneric1 {
public static void main(String[] args) {
List arrList = new ArrayList();

arrList.add(10);
arrList.add(new Integer(100));
arrList.add("Hello World !");
}
}



Untuk mengambil kembali nilai yang disimpan oleh arrList ini maka kita harus "hafal" urutan input dengan meta / tipe datanya masing-masing. Kita modifikasi kode di atas sehingga menjadi seperti berikut ini.

Contoh:


import java.util.ArrayList;
import java.util.List;

public class BeforeGeneric1 {
public static void main(String[] args) {
List arrList = new ArrayList();

arrList.add(10);
arrList.add(new Integer(100));
arrList.add("Hello World !");


int a = ((Integer) arrList.get(0)).intValue(); //casting ke int
Integer b = (Integer) arrList.get(1); //casting kembali ke objek bertipe Integer
String c = (String) arrList.get(2); //casting kembali ke objek bertipe String

System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}



Output:

10
100
Hello World !


Perhatikan bahwa untuk setiap akses nilai dari arrList ini, kita perlu melakukan konversi (casting) untuk tiap variabel dengan benar sesuai tipe data asalnya sehingga tidak terjadi error.

Jika kita melakukan kesalahan casting maka pada saat kompilasi akan diberikan pesan error seperti pada contoh di bawah ini.

Contoh:


import java.util.ArrayList;
import java.util.List;

public class BeforeGeneric1 {
public static void main(String[] args) {
List arrList = new ArrayList();

arrList.add(10);
arrList.add(new Integer(100));
arrList.add("Hello World !");


int a = ((Integer) arrList.get(0)).intValue(); //casting ke int
Integer b = (Integer) arrList.get(1); //casting kembali ke objek bertipe Integer
String c = (Integer) arrList.get(2); //casting kembali ke objek bertipe String

System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}



Error Output:

BeforeGeneric1.java:15: incompatible types
found : java.lang.Integer
required: java.lang.String
String c = (Integer) arrList.get(2); //casting kembali ke objek
bertipe String
^
Note: BeforeGeneric1.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Tidak Ada Kesalahan Pada Saat Kompilasi

Pada prakteknya biasanya ArrayList ini digunakan untuk menyimpan list dengan tipe data yang sama dan diakses dengan melakukan iterasi (perulangan .loop).

Masalah kemudian timbul apabila pada saat kita mengambil nilai dari list tersebut dan terjadi kesalahan casting.

Lihat contoh berikut di bawah ini. Pada saat kompilasi kode ini tidak akan terjadi error karena compiler belum "mengenali" kesalahan tersebut. Error hanya akan terlihat setelah hasil kompilasi tersebut dijalankan atau pada saat runtime.


Contoh:


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BeforeGeneric2 {
public static void main(String[] args) {
List arrList = new ArrayList();
for (int i = 0; i < 10; i++) {
arrList.add("Hello World");
}

Iterator i = arrList.iterator();

System.out.println("Deretan Angka Genap");
System.out.println("===================");
while (i.hasNext()) {
int a;
a = (Integer) i.next() * 2;
System.out.print("Hasil = " + a + "\n");
}
}
}


Error Output:
Deretan Angka Genap
===================
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at BeforeGeneric2.main(BeforeGeneric2.java:19)


Generic Sebagai Penyelamat

Untuk mengatasi hal tersebut di atas, maka digunakanlah suatu "parameter tipe" pada saat deklarasi objek yang disebut dengan generic.

Syntaxnya kira-kira sebagai berikut :

Class<tipe> objek = new Class<tipe>();

Untuk kasus di atas kita menetapkan bahwa tipe yang akan kita gunakan adalah Integer. Maka code di atas kita ubah menjadi :



import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class AfterGeneric {
public static void main(String[] args) {
List arrList = new ArrayList();
for (int i = 0; i < 10; i++) {
arrList.add(i);
}

Iterator i = arrList.iterator();

System.out.println("Deretan Angka Genap");
System.out.println("===================");
while (i.hasNext()) {
int a;
a = i.next() * 2;
System.out.print("Hasil = " + a + "\n");
}
}
}

Output:
Deretan Angka Genap
===================
Hasil = 0
Hasil = 2
Hasil = 4
Hasil = 6
Hasil = 8
Hasil = 10
Hasil = 12
Hasil = 14
Hasil = 16
Hasil = 18


Dari kode di atas dapat dilihat bahwa kita "menetapkan" bahwa tipe data yang diterima oleh ArrList harus berupa Integer atau int, sedangkan tipe lain akan mengalami error pada saat kompilasi.

Ini kelihatan seperti array, lalu apa kelebihannya Generic ?

Salah satu permasalahan dengan menggunakan array adalah kita harus menetapkan jumlah elemen di array pada saat deklarasi, contohnya :

  Integer[] a = new Integer[5];


Sedangkan pada penggunaan generic, kita cukup mendeklarasikan :

  List<Integer> arrList = new ArrayList<Integer>();


dan kita bisa mengalokasikan jumlah elemen secara dinamis karena ArrayList merupakan collection di dalam Java.


Bacaan Lebih Lanjut

Untuk bacaan lebih lanjut penulis menyarankan buku "Java Generics and Collections" terbitan O'Reilly.

3 comments:

panoes said...

wahh makasih bgt tutorial generikny Mbak Feris, pengetahuan sy makin tercerahkn nih!

Lambang said...

KK...
mau nanya neh...
kalo ArrayList atau Vector cuman bisa diisi Object yang dari java aja..

Bisa ga buat nyimpen tipe bentukan atau object yang kita buat sendiri.
-thx-

dendy said...

hi...I am pleased visit your blog,because update my knowledge..nice tutorial.