Java: Generics
IF2210 – Semester II 2020/2021
by: RSP; rev: SAR
1
Pengantar
› Pada proyek pengembangan perangkat lunak sering muncul
bug. Dengan perencanaan, programming, dan testing yang
baik akan mereduksi munculnya bug.
› Ada bug yang lebih mudah dideteksi yaitu compile-time bug
(dibandingkan run-time bug).
› Dengan menggunakan konsep Generik akan menambah
stabilitas kode dengan membuat bug terdeteksi saat
kompilasi.
31/03/2021 IF2210/Java/Generics 2
Contoh: simple box
public class SimpleBox {
private Object object;
public void put(Object object) { [Link] = object; }
public Object get() { return object; }
}
public class SimpleBoxDemo1 {
public static void main(String[] args) {
// ONLY place Integer objects into this box!
SimpleBox intBox = new SimpleBox();
[Link](10);
int someInt = (int) [Link]();
[Link](someInt);
}
}
31/03/2021 IF2210/Java/Generics 3
public class SimpleBoxDemo2 {
public static void main(String[] args) {
// ONLY place Integer objects into this box!
SimpleBox intBox = new SimpleBox();
[Link]("10"); // Someone may mistakenly put a String...
int someInt = (int) [Link]();
[Link](someInt);
}
}
Menyebabkan run-time exception:
Exception in thread "main"
[Link]:
class [Link] cannot be cast to class [Link]
at [Link]([Link])
31/03/2021 IF2210/Java/Generics 4
Generic pada Java
› Kelas generik pada java diimplementasikan sebagai
parameter tipe.
› Hasil kompilasi kode kelas generik tetap hanya satu kelas,
dengan parameter tipe yang diganti dengan tipe riil pada saat
runtime.
› pada C++, kompilasi class template menghasilkan kelas yang
berbeda untuk setiap tipe generik.
› Keuntungan generik:
› Meningkatkan expressive power.
› Meningkatkan type safety.
› Mengeksplisitkan parameter tipe dan mengimplisitkan type
casting.
31/03/2021 IF2210/Java/Generics 5
Sintaks Generik
› Mendefinisikan kelas & interface:
› class NamaKelas<TipeGenerik> { ... }
› interface NamaInterface<TipeGenerik> { ... }
› class NamaKelas<TipeGenerik1, TipeGenerik2> { ... }
› interface NamaInterface<TipeGenerik1, TipeGenerik2> { ... }
› Nama untuk parameter tipe generik sebaiknya menggunakan
sebuah karakter huruf besar, misalnya E atau T.
› Kita dapat mendefinisikan lebih dari satu parameter tipe.
31/03/2021 IF2210/Java/Generics 6
Konvensi Penamaan Tipe
› E - Element (used extensively by the Java Collections
Framework)
› K - Key
› N - Number
› T - Type
› V - Value
› S, U, V etc. - 2nd, 3rd, 4th types
Copyright © 2008, 2010 Oracle and/or its affiliates
Contoh: generic box
public class Box<T> {
private T t;
public void put(T t) { this.t = t; }
public T get() { return t; }
}
public class GenericBoxDemo1 {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>(); // "diamond notation" for ctor
[Link](10);
int someInt = [Link](); // no casting needed
[Link](someInt);
}
}
31/03/2021 IF2210/Java/Generics 8
public class GenericBoxDemo2 {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
[Link]("10");
int someInt = [Link]();
[Link](someInt);
}
}
Menyebabkan compile error:
Error:(7, 20) java: incompatible types: [Link] cannot be
converted to [Link]
31/03/2021 IF2210/Java/Generics 9
Generic methods & constructors
› Type parameter dapat juga digunakan pada method dan
konstruktor menjadi generic methods dan generic
constructors.
public class Box<T> {
// ...
public <U> void inspect(U u) {
[Link]("T: " + [Link]().getName());
[Link]("U: " + [Link]().getName());
}
// ...
}
// Somewhere else...
Box<Integer> intBox = new Box<>();
[Link](10);
[Link]("10");
31/03/2021 IF2210/Java/Generics 10
Type inference
› Compiler dapat mengetahui tipe parameter pada pemanggilan
method generik dari tipe argumennya.
public class Box<T> {
// ...
public static <U> void fillBoxes(U u, List<Box<U>> boxes) {
for (Box<U> box: boxes) [Link](u);
}
// ...
}
// Somewhere else...
Crayon red = new Crayon("red");
List<Box<Crayon>> crayonBoxes = new ArrayList<>();
Box.<Crayon>fillBoxes(red, crayonBoxes);
[Link](red, crayonBoxes); // compiler infers that U is Crayon
31/03/2021 IF2210/Java/Generics 11
Bounded type parameters
› Ada kebutuhan untuk membatasi tipe-tipe apa saja yang
diberbolehkan untuk masuk sebagai parameter.
› Sebagai contoh mengharapkan hanya tipe angka (Number dan
turunannya) yang boleh.
public class Box<T> {
// ...
public <U extends Number> void boundedInspect(U u) {
[Link]("T: " + [Link]().getName());
[Link]("U: " + [Link]().getName());
}
// ...
}
31/03/2021 IF2210/Java/Generics 12
public class BoundedTypeParamDemo {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
[Link](10);
[Link]("10"); // error, String does not
// extend Number
}
}
Menyebabkan compile error:
Error:(7, 15) java: method boundedInspect in class Box<T> cannot be
applied to given types;
required: U
found: [Link]
reason: inference variable U has incompatible bounds
lower bounds: [Link]
lower bounds: [Link]
31/03/2021 IF2210/Java/Generics 13
Bound dengan interface
› Tetap menggunakan keyword extends (bukan implements).
› Jika lebih dari satu, gabungkan dengan operator &.
› Contoh:
public <T extends SomeInterface> void a(T t) {...}
public <U extends Number & SomeInterface> void b(U u) {...}
31/03/2021 IF2210/Java/Generics 14
Subtyping (1)
› Ingat kembali relasi “is a”. Jika D extends atau implements
B, maka semua reference ke B dapat di-assign dengan objek
dari kelas D.
› Contoh: Integer extends Number, maka dapat dilakukan:
Number aNumber;
Integer anInt = new Integer(10);
aNumber = anInt; // OK
31/03/2021 IF2210/Java/Generics 15
Subtyping (2)
› Berlaku juga untuk pemanggilan method:
public void someMethod(Number n) {/*...*/}
// somewhere else...
someMethod(new Integer(10)); // OK
someMethod(new Double(10.0)); // OK
› dan pada tipe generik:
Box<Number> box = new Box<>();
[Link](new Integer(10)); // OK
[Link](new Double(10.0)); // OK
31/03/2021 IF2210/Java/Generics 16
Subtyping (3)
› Bolehkah:
public void doSomethingToBoxOfNumber(Box<Number> b) {
/*...*/
}
// somewhere else:
Box<Integer> intBox = new Box<>();
Box<Double> dblBox = new Box<>();
doSomethingToBoxOfNumber(intBox);
doSomethingToBoxOfNumber(dblBox);
?
› Akan dibahas pada materi wildcard.
31/03/2021 IF2210/Java/Generics 17
Type erasure (1)
› Bila tipe generik digunakan maka kompilator akan membuang
semua informasi yang berhubungan dengan tipe parameter dalam
kelas atau method.
› T digantikan dengan bound-nya atau Object, jika unbounded.
› Ditambahkan typecasting.
› Dibangkitkan method antara sebagai jembatan.
› Satu kelas generik pada source code (.java) hanya dikompilasi
menjadi satu kelas dalam bytecode, berbeda dari template di C++,
C# yang membangkitkan kelas-kelas untuk setiap parameter
template yang digunakan.
31/03/2021 IF2210/Java/Generics 18
Tugas Baca #8A
› Tugas: baca artikel-artikel berikut terkait type erasure:
› [Link]/articles/java-generics-type-erasure/
› [Link]/questions/31693/what-are-the-
differences-between-generics-in-c-sharp-and-java-and-
templates-i
31/03/2021 IF2210/Java/Generics 19
Tugas Baca #8B
› Gast, H. (2015). How to use objects: code and concepts.
Addison-Wesley Professional.
› Chapter 3 (semua)
› Buat summary min. 1 halaman, max. 3 halaman
› excluding header e.g. nama, NIM
› excluding baris kosong e.g. Enter 2×
› Pengumpulan: Google Classroom
Not OK OK OK OK
31/03/2021 IF2210/Bahasa Java/Pengenalan Java 20