Generics, java 1.5 ile Java da yer almaya başlamış, nesneye Object türünden başka türler belirterek kullanım kolaylığının yanı sıra, daha okunaklı, bakımı ve geliştirilmesi daha kolay kod yazımını sağlamıştır.

Örnek olarak vermek gerekirsek, Vector tipini ele alalım. Eğer siz Vector‘ünüzü;

Vector myVector = new Vector();

şeklinde yaratırsanız, size get metodunda Object türünden nesneler dönüp, set metodunda ise Object türünde nesne isteyecektir. Siz her seferinde bu Vector‘e String nesnesi koysanız bile, her aldığınızda kendiniz String nesnesine cast etmek zorunda kalırsınız.

Ancak siz aynı Vector‘ünüzü;

Vector<String> myVector = new Vector<String>();

şeklinde yaratırsanız, size get metodundan String türü dönecek, set metodunda ise String türünde nesne isteyecektir. Siz her seferinde get ile aldığınız nesneleri cast etmek zorunda kalmayacak ve kodlama sırasında farklı türden bir nesneyi set etmeye ya da ona get etmeye çalışmanız halinde compile-time hata vererek, olası run-time hatalarından kurtaracaktır.

Generic’lerde dikkat edilmesi gereken bir husus, Vector bir tür değildir. Vector<String>.class mantıksız olacak ve compile-time da hata verecektir. Generic’ler sadece birer belirteç gibi görebilirsiniz. Sizi sadece bazı hatalardan koruyarak, sizin bu hataları yapmanızı engelleyip, arka planda aslında yine cast işlemlerini yaparlar. Vector sınıfının kaynak koduna bakarsanız, orada verileri bir Object[] dizisinde tutup, get metodunda da o diziden aldığı Object türündeki nesneyi generic türüne cast etmektedir. Java compiler da siz kodunuzu binary hale dönüştürdüğünüzde, oradaki generic imzalarını verdiğiniz türe çekerek compile eder.

Nasıl Vector bir tür değilse; Vector myVector = new Vector(); şeklinde bir generic Vector tanımlamak, generic‘siz bir Vector tanımlamakla eşdeğerdir. Çünkü soru işareti (?) herhangi bir tür olduğunu belirtir. Ancak wild card şu şekilde kullanırsak;

public void myMethod(Vector<? extends String> paramVector) {
    // method body
}

burada da, String ve ondan türemiş diğer nesneleri kabul eder şeklinde bir wild card kullanmış oluruz. Yine metod, en az String veya String‘den türemiş bir nesne isteyecektir. Object ya da String türünden farklı bir nesne gönderimi compile-time da hata verecektir.

Sınıfları ve metod parametrelerini generic olarak yazmanın yanı sıra, bir metodun dönüş değerini de generic olarak tanımlayabiliriz. Örnek vermek gerekirse;

public <T> T myMethod(String p_strParam, Class<T> p_typeParam){
    return (T) p_strParam;
}

myMethod metodu, T türünden bir nesne dönmektedir. Nesnenin asıl türünü ise parametre ile gönderilen sınıftan almaktadır. eğer metodu şu şekilde çağrırısak; myObj.myMethod("my parameter", String.class);

içeride “my parameter” ı String nesnesine cast edip return edecektir. Ancak burada dikkat edilmesi gereken nokta, bu gibi benzer durumlarda, burada bir String nesnesini T nesnese (ki herşey olabilir) cast ediyoruz. Bu da compile-time da warning verecektir.

Sonuç olarak java da generic‘ler, daha generic (DRY:don’t repeat yourself) kodlar yazmanıza olanak sağlıyarak, daha efektif çalışmanıza imkan verecektir.