Yang kita tahu adalah " Semua instance dari kelas apa pun berbagi objek java.lang.Class yang sama dari jenis kelas "
misalnya)
Student a = new Student();
Student b = new Student();
Maka a.getClass() == b.getClass()
itu benar.
Sekarang anggaplah
Teacher t = new Teacher();
tanpa obat generik, di bawah ini dimungkinkan.
Class studentClassRef = t.getClass();
Tapi ini salah sekarang ..?
misalnya) public void printStudentClassInfo(Class studentClassRef) {}
dapat dipanggil denganTeacher.class
Ini bisa dihindari menggunakan obat generik.
Class<Student> studentClassRef = t.getClass(); //Compilation error.
Sekarang apa itu T ?? T adalah tipe parameter (juga disebut variabel tipe); dibatasi oleh kurung sudut (<>), mengikuti nama kelas.
T hanyalah simbol, seperti nama variabel (dapat berupa nama apa saja) yang dideklarasikan saat menulis file kelas. Nanti T itu akan diganti dengan
nama Kelas yang valid selama inisialisasi ( HashMap<String> map = new HashMap<String>();
)
misalnya) class name<T1, T2, ..., Tn>
Jadi Class<T>
mewakili objek kelas dari tipe kelas spesifik ' T
'.
Asumsikan bahwa metode kelas Anda harus bekerja dengan parameter tipe yang tidak dikenal seperti di bawah ini
/**
* Generic version of the Car class.
* @param <T> the type of the value
*/
public class Car<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Di sini T dapat digunakan sebagai String
tipe sebagai CarName
ATAU T dapat digunakan sebagai Integer
tipe sebagai modelNumber ,
ATAU T dapat digunakan sebagai Object
jenis sebagai instance mobil yang valid .
Sekarang di sini yang di atas adalah POJO sederhana yang dapat digunakan secara berbeda saat runtime.
Collections eg) List, Set, Hashmap adalah contoh terbaik yang akan bekerja dengan objek yang berbeda sesuai dengan deklarasi T, tetapi begitu kita mendeklarasikan T sebagai String
misalnya) HashMap<String> map = new HashMap<String>();
Maka ia hanya akan menerima objek instance String Class.
Metode Generik
Metode generik adalah metode yang memperkenalkan parameter tipe mereka sendiri. Ini mirip dengan mendeklarasikan tipe generik, tetapi lingkup parameter tipe terbatas pada metode yang dideklarasikan. Metode statis dan non-statis generik diperbolehkan, serta konstruktor kelas generik.
Sintaks untuk metode generik termasuk parameter tipe, kurung sudut dalam, dan muncul sebelum tipe pengembalian metode. Untuk metode generik, bagian parameter tipe harus muncul sebelum tipe pengembalian metode.
class Util {
// Generic static method
public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
class Pair<K, V> {
private K key;
private V value;
}
Berikut <K, V, Z, Y>
ini adalah deklarasi jenis yang digunakan dalam argumen metode yang harus sebelum jenis kembali yang ada di boolean
sini.
Di bawah ini; deklarasi tipe <T>
tidak diperlukan pada level metode, karena sudah dideklarasikan di level kelas.
class MyClass<T> {
private T myMethod(T a){
return a;
}
}
Tetapi di bawah ini salah karena parameter tipe tingkat kelas K, V, Z, dan Y tidak dapat digunakan dalam konteks statis (metode statis di sini).
class Util <K, V, Z, Y>{
// Generic static method
public static boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
SKENARIO VALID LAINNYA ADALAH
class MyClass<T> {
//Type declaration <T> already done at class level
private T myMethod(T a){
return a;
}
//<T> is overriding the T declared at Class level;
//So There is no ClassCastException though a is not the type of T declared at MyClass<T>.
private <T> T myMethod1(Object a){
return (T) a;
}
//Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).
private T myMethod1(Object a){
return (T) a;
}
// No ClassCastException
// MyClass<String> obj= new MyClass<String>();
// obj.myMethod2(Integer.valueOf("1"));
// Since type T is redefined at this method level.
private <T> T myMethod2(T a){
return a;
}
// No ClassCastException for the below
// MyClass<String> o= new MyClass<String>();
// o.myMethod3(Integer.valueOf("1").getClass())
// Since <T> is undefined within this method;
// And MyClass<T> don't have impact here
private <T> T myMethod3(Class a){
return (T) a;
}
// ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())
// Should be o.myMethod3(String.valueOf("1").getClass())
private T myMethod3(Class a){
return (T) a;
}
// Class<T> a :: a is Class object of type T
//<T> is overriding of class level type declaration;
private <T> Class<T> myMethod4(Class<T> a){
return a;
}
}
Dan akhirnya metode statis selalu membutuhkan <T>
deklarasi eksplisit ; Itu tidak akan berasal dari tingkat kelas Class<T>
. Ini karena level Kelas T terikat dengan instance.
Baca juga Pembatasan Generik
Wildcard dan Subtyping
ketik argumen untuk metode generik