Java Generic Yapılar: Avantajları, Kullanımı ve En İyi Uygulamalar
Java Generic yapılar, derleme zamanında tip güvenliği sağlayarak çalışma zamanı hatalarını ortadan kaldırır.
Bu rehberde generics’in temel mantığını, sınıf/metot tanımlamalarını, wildcard (?) kullanımlarını ve Type Erasure kavramını öğreneceksiniz.
💡 Bu Rehberde Ne Öğreneceksiniz?
- Java Generic yapıların faydaları ve çalışma prensibi
- Generic sınıf, metot ve arayüz tanımlama örnekleri
- Wildcard (
?),extends,superve tip sınırlandırmaları - Type Erasure kavramı ve generics’in sınırlamaları
- Kodda tip güvenliği ve okunabilirliği artırma yöntemleri
🧠 Generic Yapı Nedir ve Neden Önemlidir?
Generic yapılar, sınıf veya metotları belirli bir tipe bağlı kalmadan tanımlamanızı sağlar.
Tip, kullanım anında belirlenir ve derleme zamanında kontrol edilir.
Generics’in Sağladığı Avantajlar
- ✅ Tip Güvenliği: ClassCastException hatalarını ortadan kaldırır.
- ✅ Kod Tekrarını Azaltır: Tek bir kod bloğu, farklı tiplerle yeniden kullanılabilir.
- ✅ Okunabilirlik: Tip dönüşümü (casting) ihtiyacını ortadan kaldırır.
⚙️ Koleksiyonlarda Generics Kullanımı
Öncesi (Hatalı Kullanım)
List list = new ArrayList();
list.add("abc");
list.add(new Integer(5)); // Derleme zamanı hata yok ama runtime'da çakılır
for(Object obj : list){
String str = (String) obj; // ClassCastException
}
Sonrası (Tip Güvenliği Sağlanmış)
List<String> list1 = new ArrayList<>();
list1.add("abc");
// list1.add(5); // Derleme hatası verir, tip güvenliği sağlanır.
for(String str : list1){
System.out.println(str); // Casting gerekmez
}
💻 Kendi Generic Sınıfınızı Oluşturma
// T tipi, sınıf kullanımında belirlenir (örneğin String, Integer)
public class GenericTip<T> {
private T t;
public T get() { return this.t; }
public void set(T t1) { this.t = t1; }
public static void main(String[] args){
GenericTip<String> g1 = new GenericTip<>();
g1.set("Rabisu Cloud");
GenericTip<Integer> g2 = new GenericTip<>();
g2.set(2025);
}
}
💬 Bu yapı, tür dönüşümünü ortadan kaldırır ve kodu daha güvenli hale getirir.
🧩 Generic Arayüzler ve Tip İsimlendirme
| Parametre | Anlam | Örnek Kullanım |
|---|---|---|
| E | Element (Öğe) | List<E>, Set<E> |
| K | Key (Anahtar) | Map<K, V> |
| V | Value (Değer) | Map<K, V> |
| T | Type (Tip) | GenericClass<T> |
| N | Number (Sayı) | Sayısal tiplerle (Integer, Double) |
🧮 Generic Metot Tanımlama
// İki generic nesnenin içeriklerini karşılaştırır.
public static <T> boolean esitMi(GenericTip<T> g1, GenericTip<T> g2){
return g1.get().equals(g2.get());
}
💬 Tip parametresi metodun dönüş tipinden önce belirtilir.
🧱 Sınırlandırılmış Tipler (Bounded Types)
extends anahtar kelimesi, bir generic tipin hangi türleri kabul edeceğini sınırlar.
// Sadece Comparable arayüzünü uygulayan tiplerle çalışır
public static <T extends Comparable<T>> int karsilastir(T t1, T t2){
return t1.compareTo(t2);
}
💬 Bu örnek, sadece Comparable arayüzüne sahip sınıflarda geçerlidir.
🌀 Wildcard (Joker Karakter) Kullanımı
Wildcard (?) bilinmeyen tipi temsil eder ve esneklik sağlar.
Üst Sınırlandırma – ? extends T
Okuma işlemleri için kullanılır (ekleme yapılamaz).
public static double topla(List<? extends Number> liste){
double toplam = 0;
for(Number n : liste){
toplam += n.doubleValue();
}
return toplam;
}
Alt Sınırlandırma – ? super T
Yazma işlemleri için kullanılır (okuma kısıtlıdır).
public static void tamsayiEkle(List<? super Integer> liste){
liste.add(50);
}
🧬 Type Erasure (Tip Silme)
Java, generics bilgilerini yalnızca derleme zamanında kullanır. Çalışma zamanında tüm tip parametreleri Object ile değiştirilir.
public class Test<T extends Comparable<T>> {
private T data;
public T getData() { return data; }
}
Derleme sonrası:
public class Test {
private Comparable data;
public Comparable getData() { return data; }
}
💬 Bu sayede generics performansa ek yük getirmez.
❓ Sıkça Sorulan Sorular (SSS)
- Neden Generic diziler oluşturulamaz?
Çünkü generics bilgisi çalışma zamanında silinir (Type Erasure). Diziler runtime tip kontrolü ister.
- Raw Type (Ham Tip) nedir?
Generic sınıfın tip parametresi belirtilmeden kullanılmasıdır (List yerine List<String>). Kullanılması önerilmez.
- Neden primitive tipler (int, boolean) kullanılamaz?
Generic’ler yalnızca referans tiplerini destekler. int yerine Integer kullanılmalıdır.
- Generics kalıtımda nasıl davranır?
String, Object’in alt sınıfı olsa da List<String> hiçbir zaman List<Object> değildir. Bu durum wildcard ile aşılabilir.
- Generics neden güvenlidir?
Derleme zamanı tip kontrolü yapar, böylece ClassCastException gibi hataları önler.
🔚 Sonuç
Java Generic yapılar, modern ve hatasız Java kodunun temelidir. Tip güvenliği, okunabilirlik ve bakım kolaylığı sağlar. Wildcards, bounded tipler ve type erasure kavramlarını anlayarak kodunuzu daha profesyonel hale getirebilirsiniz.
💡 Rabisu Bulut platformunda generics destekli Java uygulamalarınızı hemen test edin ve ölçeklenebilir altyapınızı oluşturun! 🚀