Menu
Coddy logo textTech

Generics'e Giriş

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 53 / 87.

Daha sonra geri almak üzere bir değer depolayan bir sınıf oluşturmanız gerektiğini düşünün. Jenerikler olmadan, her tür için ayrı sınıflar yazmanız gerekirdi: Integer için bir tane, String için bir tane, Double için bir tane ve bu şekilde devam eder. Bu durum kod tekrarına ve bakım sorunlarına yol açar.

Generikler, tür güvenliğini korurken herhangi bir türle çalışan sınıflar ve metotlar yazmanıza olanak tanıyarak bu sorunu çözer. Bir sınıfı kullandığınızda gerçek bir türle değiştirilen bir yer tutucu (tür parametresi olarak adlandırılır) tanımlarsınız:

// Jenerikler olmadan - Object kullanır, casting gerektirir
List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0);  // Manuel casting gerekli

// Jeneriklerle - tip güvenli, casting yok
List<String> list = new ArrayList<String>();
list.add("Hello");
String s = list.get(0);  // Casting gerekmez

Açı parantezleri <T> bir tür parametresini belirtir. List<String> yazdığında, derleyiciye bu listede yalnızca dizelerin bulunacağını söylersin. Bir tamsayı eklemeye çalışırsan derleyici, çalışma zamanında başarısız olmak yerine hatayı hemen yakalar.

Jenerikler iki temel fayda sağlar: açık tür dönüştürme gereksinimini ortadan kaldırır ve tür hatalarını çalışma zamanı yerine derleme zamanında yakalar. Bu, kodunuzu hem daha güvenli hem de daha temiz hâle getirir. Sonraki derslerde, kendi jenerik sınıflarınızı ve yöntemlerinizi nasıl oluşturacağınızı inceleyeceğiz.

challenge icon

Görev

Kolay

Object kullanarak dönüştürme yapılan eski yöntem ile tür güvenliği sağlayan generic'leri kullanan yeni yöntemi karşılaştırarak generic'lerin gücünü gösteren basit bir depolama sistemi oluşturalım.

Aradaki farkı ilk elden görmek için üç dosya oluşturacaksınız:

  • OldBox.java: Değerleri generic'lerden önceki yöntemle depolayan bir sınıf oluşturun. OldBox sınıfınızda content türünde, private bir Object alanı bulunmalıdır. Bir Object kabul edip bunu depolayan bir kurucu ve Object döndüren bir getContent() yöntemi ekleyin. Bu yaklaşım çalışır, ancak değerleri alırken dönüştürme yapılmasını gerektirir.
  • GenericBox.java: Şimdi generic'leri kullanarak modern ve tür güvenli sürümü oluşturun. GenericBox bildiriminde T tür parametresini kullanmalıdır. content türünde private bir T alanına, T türünde bir değer kabul eden bir kurucuya ve getContent() türünü döndüren bir T yöntemine ihtiyacı vardır. Bu sınıfı kullanırken dönüştürme gerekmez!
  • Main.java: Her iki yaklaşımı yan yana gösterin. İki girdi alacaksınız: bir sözcük (String) ve bir sayı (integer).

    İlk olarak eski yaklaşımı kullanın: sözcüğü depolayan bir OldBox oluşturun, ardından String'e dönüştürerek geri alın ve şunu yazdırın: OldBox (with cast): [value]

    Ardından generic yaklaşımı kullanın: aynı sözcüğü depolayan bir GenericBox<String> oluşturun, dönüştürme yapmadan geri alın ve şunu yazdırın: GenericBox (no cast): [value]

    Sonra generic'lerin tamsayılarla çalıştığını gösterin: sayıyı depolayan bir GenericBox<Integer> oluşturun, sayıyı geri alın ve şunu yazdırın: GenericBox Integer: [value]

    Son olarak boş bir satırın ardından şunu yazdırın: Type safety: Generics catch errors at compile time!

Sırayla iki girdi alacaksınız: bir sözcük (String) ve bir sayı (parse edeceğiniz String olarak integer).

Temel farka dikkat edin: OldBox ile (String) box.getContent() dönüşümünü yapmalı ve türü doğru aldığınızı ummalısınız. GenericBox ile derleyici türü bilir ve dönüştürme gerekmez. Generic'lerin temel faydası budur: dönüştürme zahmeti olmadan tür güvenliği!

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String word = scanner.nextLine();
        int number = Integer.parseInt(scanner.nextLine());
        
        // TODO: Kelimeyi saklayan bir OldBox oluştur
        // Retrieve with cast to String and print: "OldBox (with cast): [value]"
        
        // TODO: Kelimeyi saklayan bir GenericBox<String> oluştur
        // Retrieve without casting and print: "GenericBox (no cast): [value]"
        
        // TODO: Create a GenericBox<Integer> storing the number
        // Retrieve and print: "GenericBox Integer: [value]"
        
        // TODO: Boş bir satır yazdır, sonra yazdır:
        // "Type safety: Generics catch errors at compile time!"
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Java derleyicisi