Bildiğimiz tek şey, " Herhangi bir sınıfın tüm örnekleri, bu tür bir sınıfın aynı java.lang.Class nesnesini paylaşır "
Örneğin)
Student a = new Student();
Student b = new Student();
O zaman a.getClass() == b.getClass()
doğrudur.
Şimdi varsayalım
Teacher t = new Teacher();
jenerikler olmadan aşağıdakiler mümkündür.
Class studentClassRef = t.getClass();
Ama bu şimdi yanlış ..?
örneğin) public void printStudentClassInfo(Class studentClassRef) {}
ile çağrılabilirTeacher.class
Bu, jenerikler kullanılarak önlenebilir.
Class<Student> studentClassRef = t.getClass(); //Compilation error.
Şimdi T nedir ?? T, tip parametreleridir (tip değişkenleri olarak da adlandırılır); köşeli parantez (<>) ile sınırlandırılmış, sınıf adını izler.
T, sınıf dosyasının yazılması sırasında bildirilen bir değişken adı (herhangi bir ad olabilir) gibi sadece bir semboldür. Daha sonra T,
başlatma sırasında geçerli Sınıf adıyla değiştirilir ( HashMap<String> map = new HashMap<String>();
)
Örneğin) class name<T1, T2, ..., Tn>
Yani Class<T>
belirli sınıf türündeki bir sınıf nesnesini temsil eder ' T
'
Sınıf yöntemlerinizin aşağıdaki gibi bilinmeyen tür parametreleriyle çalışması gerektiğini varsayın
/**
* 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; }
}
Burada T, CarName olarak String
tip olarak kullanılabilir
VEYA T modelNumber olarak Integer
tip olarak kullanılabilir ,
VEYA T geçerli araba örneği olarak Object
tip olarak kullanılabilir .
Şimdi burada yukarıda çalışma zamanında farklı olarak kullanılabilecek basit POJO var.
Koleksiyonlar örn.) List, Set, Hashmap, T bildirimi uyarınca farklı nesnelerle çalışacak en iyi örneklerdir, ancak T'yi String olarak ilan ettikten sonra,
örneğin) HashMap<String> map = new HashMap<String>();
Sadece String Class örnek nesnelerini kabul eder.
Genel Yöntemler
Genel yöntemler, kendi tür parametrelerini tanıtan yöntemlerdir. Bu, genel bir tür bildirmeye benzer, ancak tür parametresinin kapsamı bildirildiği yöntemle sınırlıdır. Statik ve statik olmayan jenerik yöntemlerin yanı sıra genel sınıf yapıcılarına izin verilir.
Genel bir yöntemin sözdizimi bir tür parametresi, iç köşeli parantezler içerir ve yöntemin dönüş türünden önce görünür. Genel yöntemler için, type parametresi bölümü, yöntemin dönüş türünden önce görünmelidir.
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;
}
Burada <K, V, Z, Y>
yöntem argümanlar kullanılan türde beyanı olan should olan dönüş türü önce boolean
burada.
Aşağıda; <T>
sınıf düzeyinde zaten bildirildiğinden, yöntem düzeyinde tür bildirimi gerekli değildir.
class MyClass<T> {
private T myMethod(T a){
return a;
}
}
Ancak, sınıf düzeyinde tip parametreleri K, V, Z ve Y statik bir bağlamda kullanılamadığından (burada statik yöntem) aşağıda yanlıştır.
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());
}
}
DİĞER GEÇERLİ SENARYOLAR
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;
}
}
Ve son olarak, Statik yöntem her zaman açık bir <T>
beyan gerektirir; Sınıf seviyesinden türetilmeyecektir Class<T>
. Bunun nedeni, Sınıf seviyesi T'nin örneğe bağlı olmasıdır.
Ayrıca Jeneriklerle İlgili Kısıtlamalar'ı okuyun
Joker Karakterler ve Alt Türlendirme
genel bir yöntem için argüman yazın