Menu
CoddyTech

Generics'e Giriş

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

Bir değeri saklayan ve daha sonra geri alan bir sınıf oluşturman gerektiğini düşün. Generics olmadan her tür için ayrı sınıflar yazman gerekir: biri Integer için, biri String için, biri Double için ve böyle devam eder. Bu da kod tekrarına ve bakım zorluklarına yol açar.

Generics, tür güvenliğini korurken herhangi bir türle çalışan sınıflar ve metotlar yazmana olanak tanıyarak bu sorunu çözer. Sınıfı kullanırken gerçek bir türle değiştirilen bir yer tutucu ( tür parametresi olarak adlandırılır) tanımlarsın:

// Generics olmadan - Object kullanır, tür dönüşümü gerektirir
List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0);  // Elle tür dönüşümü gerekir

// Generics ile - tür güvenlidir, tür dönüşümü gerekmez
List<String> list = new ArrayList<String>();
list.add("Hello");
String s = list.get(0);  // Tür dönüşümü gerekmez

Açılı ayraçlar <T> bir tür parametresini belirtir. List<String> yazdığında, derleyiciye bu listenin yalnızca dizeler içereceğini söylersin. Bir tam sayı eklemeye çalışırsan, derleyici hatayı çalışma zamanında başarısız olmak yerine hemen yakalar.

Jenerikler iki önemli avantaj 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, kodunu hem daha güvenli hem de daha temiz hâle getirir. Sonraki derslerde, kendi jenerik sınıflarını ve metotlarını nasıl oluşturacağını inceleyeceğiz.

challenge icon

Görev

Kolay

Object kullanımı ve tür dönüştürme içeren eski yöntemi, tür güvenliği sağlayan generic'lerle kullanılan yeni yöntemle karşılaştırarak generic'lerin gücünü gösteren basit bir depolama sistemi oluşturalım.

Farkı kendi gözlerinle görmek için üç dosya oluşturacaksın:

  • OldBox.java: Değerleri generic'lerden önceki yöntemle saklayan bir sınıf oluştur. OldBox sınıfında, türü Object olan bir content özel alanı bulunmalı. Bir Object kabul edip onu saklayan bir kurucu ve Object döndüren bir getContent() yöntemi ekle. Bu yöntem işe yarar, ancak değerleri alırken tür dönüştürme gerektirir.
  • GenericBox.java: Şimdi generic'leri kullanarak modern ve tür güvenli sürümü oluştur. GenericBox sınıfının bildiriminde bir tür parametresi T kullan. Sınıfta, türü T olan bir content özel alanı, T türünde bir değer kabul eden bir kurucu ve T türünde değer döndüren bir getContent() yöntemi bulunmalı. Bu sınıfı kullanırken tür dönüştürme gerekmez!
  • Main.java: Her iki yaklaşımı yan yana göster. İki girdi alacaksın: bir sözcük (String) ve bir sayı (integer).

    Önce eski yaklaşımı kullan: Sözcüğü saklayan bir OldBox oluştur, ardından değeri String türüne dönüştürerek al ve şunu yazdır: OldBox (with cast): [value]

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

    Sonra generic'lerin tam sayılarla çalıştığını göster: Sayıyı saklayan bir GenericBox<Integer> oluştur, değeri al ve şunu yazdır: GenericBox Integer: [value]

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

Sırayla iki girdi alacaksın: bir sözcük (String) ve bir sayı (String olarak integer; bu sayıyı ayrıştıracaksın).

Temel farka dikkat et: OldBox ile (String) box.getContent() şeklinde tür dönüştürmesi yapmalı ve türün doğru olduğunu ummalısın. GenericBox ile derleyici türü bilir ve tür dönüştürme gerekmez. Generic'lerin temel faydası budur: tür 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
        // String türüne dönüştürerek değeri al ve yazdır: "OldBox (with cast): [value]"
        
        // TODO: Kelimeyi saklayan bir GenericBox<String> oluştur
        // Tür dönüşümü yapmadan değeri al ve yazdır: "GenericBox (no cast): [value]"
        
        // TODO: Sayıyı saklayan bir GenericBox<Integer> oluştur
        // Değeri al ve yazdır: "GenericBox Integer: [value]"
        
        // TODO: Boş bir satır yazdır, ardından şunu 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