"Hai, Amigo!"
"Hai, Ellie!"
"Hari ini, Rishi dan saya akan memberitahu anda semua tentang generik."
"Tunggu, saya rasa saya sudah tahu hampir segala-galanya."
"Hampir semuanya, tetapi bukan semuanya."
"Betul ke? OK, saya sedia mendengar."
"Kalau begitu mari kita mulakan."
"Di Java, generik ialah kelas yang mempunyai parameter jenis."
"Mengenai sebab generik dicipta, lihat komen dalam kod:"
ArrayList stringList = new ArrayList();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // Add a number to the list
for(Object o: stringList)
{
String s = (String) o; // There will be an exception here when we get to the integer
}
Bagaimana untuk menyelesaikan masalah menggunakan Generik:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // There will be a compilation error here
for(Object o: stringList)
{
String s = (String) o;
}
"Kod ini tidak akan dikompilkan, dan ralat yang disebabkan oleh penambahan jenis data yang salah akan diperhatikan semasa penyusunan."
"Ya, saya sudah tahu ini."
"Okay, bagus. Pengulangan adalah ibu kepada pembelajaran."
"Tetapi pencipta Java agak malas apabila mereka mencipta generik. Daripada membuat jenis lengkap dengan parameter, mereka tergelincir dalam pengoptimuman yang licin. Pada hakikatnya, mereka tidak menambah sebarang maklumat tentang parameter jenis pada generik. Sebaliknya, semua sihir berlaku semasa penyusunan."
List<String> strings = new ArrayList<String>();
strings.add("abc");
strings.add("abc");
strings.add( 1); // Compilation error
for(String s: strings)
{
System.out.println(s);
}
List strings = new ArrayList();
strings.add((String)"abc");
strings.add((String)"abc");
strings.add((String) 1); // Compilation error
for(String s: strings)
{
System.out.println(s);
}
"Itu licin."
"Ya, tetapi pendekatan ini mempunyai kesan sampingan. Tiada maklumat tentang parameter jenis disimpan di dalam kelas generik. Pendekatan ini kemudiannya dikenali sebagai pemadaman jenis ."
"Dengan kata lain, jika anda mempunyai kelas anda sendiri dengan parameter jenis, anda tidak boleh menggunakan maklumat tentang mereka di dalam kelas."
class Zoo<T>
{
ArrayList<T> pets = new ArrayList<T>();
public T createAnimal()
{
T animal = new T();
pets.add(animal)
return animal;
}
}
class Zoo
{
ArrayList pets = new ArrayList();
public Object createAnimal()
{
Object animal = new ???();
pets.add(animal)
return animal;
}
}
"Semasa penyusunan, semua jenis parameter digantikan dengan Objek. Dan di dalam kelas tiada maklumat tentang jenis yang dihantar kepadanya."
"Ya, saya setuju, itu bukan yang terbaik."
"Taklah seram sangat. Nanti saya cerita macam mana nak atasi masalah ni."
Tetapi ada lagi. Java membolehkan anda menentukan jenis induk untuk parameter jenis. Kata kunci extends digunakan untuk ini. Sebagai contoh:
class Zoo<T extends Cat>
{
T cat;
T getCat()
{
return cat;
}
void setCat (T cat)
{
this.cat = cat;
}
String getCatName()
{
return this.cat.getName();
}
}
class Zoo
{
Cat cat;
Cat getCat()
{
return cat;
}
void setCat(Cat cat)
{
this.cat = cat;
}
String getCatName()
{
return this.cat.getName();
}
}
"Perhatikan dua fakta:"
"Pertama, anda tidak boleh melepasi sebarang jenis sahaja sebagai parameter — anda hanya boleh melepasi Cat atau kelas yang mewarisi Cat."
"Kedua, di dalam kelas Zoo, pembolehubah jenis T kini boleh memanggil kaedah kelas Cat. Lajur di sebelah kanan menerangkan sebabnya (kerana Cat akan digantikan di mana-mana terdapat T)"
"Ya. Jika kami mengatakan bahawa Cat atau subkelas Cat diluluskan sebagai hujah jenis, maka kami pasti jenis T akan sentiasa mempunyai kaedah kelas Cat."
"Nah, itu pandai."
GO TO FULL VERSION