Menu
Coddy logo textTech

Özel İstisnalar

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

Java'nın yerleşik istisnaları birçok yaygın hata senaryosunu kapsar, ancak bazen uygulamanızın alanına özgü istisnalara ihtiyaç duyarsınız. Özel istisnalar, neyin yanlış gittiğini net bir şekilde ileten anlamlı hata türleri oluşturmanıza olanak tanır.

Özel bir istisna oluşturmak için mevcut bir istisna sınıfını genişletmeniz yeterlidir. Denetlenen (checked) bir istisna için Exception sınıfını genişletin:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

Kontrol edilmeyen bir istisna için RuntimeException sınıfını genişletin:

public class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

super(message) çağrısı, hata mesajını üst sınıfa ileterek getMessage() aracılığıyla kullanılabilir hale getirir. Daha sonra kendi özel istisnanızı diğerleri gibi fırlatabilir ve yakalayabilirsiniz:

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("Balance too low: " + balance);
    }
    balance -= amount;
}

// Kullanımı
try {
    account.withdraw(1000);
} catch (InsufficientFundsException e) {
    System.out.println(e.getMessage());
}

Özel istisnalar kodunuzu daha okunabilir hale getirir ve çağıranların belirli hata durumlarını farklı şekilde ele almasına olanak tanır. Özellikle net hata iletişiminin önemli olduğu API'ler veya kütüphaneler oluştururken değerlidirler.

challenge icon

Görev

Kolay

Farklı hata senaryolarını yönetmek için özel istisnalar (custom exceptions) kullanan bir bilet rezervasyon sistemi oluşturalım! Bilet rezervasyonu sırasında neyin yanlış gittiğini net bir şekilde ileten anlamlı istisna türleri oluşturacaksınız.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • TicketSoldOutException.java: Biletler artık mevcut olmadığında kullanılacak özel bir denetimli istisna (checked exception - Exception sınıfını genişletir) oluşturun. İstisnanız, yapılandırıcısında (constructor) bir mesaj kabul etmeli ve bunu super(message) kullanarak üst sınıfa iletmelidir.
  • InvalidSeatException.java: Birisi geçersiz bir koltuk numarası rezerve etmeye çalıştığında kullanılacak özel bir denetimsiz istisna (unchecked exception - RuntimeException sınıfını genişletir) oluşturun. Bu istisna da bir mesaj kabul etmeli ve bunu üst sınıfına iletmelidir.
  • TicketBooth.java: Bilet satışlarını yöneten bir sınıf oluşturun. Gişeniz (booth), toplam mevcut koltuk sayısını ve en yüksek geçerli koltuk numarasını takip etmelidir. Şunları içermelidir:

    Mevcut toplam koltuk sayısını alan bir yapılandırıcı (constructor).

    Rezervasyonu doğrulayan bir bookTicket(int seatNumber) metodu. Hiç bilet kalmadıysa (mevcut koltuklar 0 veya daha azsa), "No tickets remaining" mesajıyla bir TicketSoldOutException fırlatın. Koltuk numarası 1'den küçük veya toplam koltuk sayısından büyükse, "Seat [seatNumber] does not exist" mesajıyla bir InvalidSeatException fırlatın. Aksi takdirde, mevcut koltuk sayısını 1 azaltın ve Booked seat [seatNumber] successfully yazdırın.

    Mevcut koltuk sayısını döndüren bir getAvailableSeats() metodu.

  • Main.java: Bilet sisteminizi bir araya getirin! İki girdi alacaksınız: toplam koltuk sayısı ve rezerve edilecek koltuk numarası.

    Verilen toplam koltuk sayısıyla bir TicketBooth oluşturun. Ardından, bir try-catch bloğu içinde belirtilen koltuk numarasını rezerve etmeye çalışın. TicketSoldOutException denetimli (checked) bir istisna olduğu için onu ele almanız gerekir. Önce TicketSoldOutException istisnasını yakalayın ve Booking failed: [exception message] yazdırın. Ardından InvalidSeatException istisnasını yakalayın ve aynı formatta yazdırın: Booking failed: [exception message].

    Try-catch bloğundan sonra, getter metodunu kullanarak Remaining seats: [count] yazdırın.

Sırasıyla iki girdi alacaksınız: toplam koltuk sayısı (tamsayı) ve rezerve edilecek koltuk numarası (tamsayı).

Denetimli istisnaların (checked exceptions) çağıranları bunları ele almaya (try-catch veya throws ile) nasıl zorladığına, denetimsiz istisnaların (unchecked exceptions) ise açıkça ele alınmasının gerekmediğine dikkat edin. İstisna türünü, hatanın çağıranların öngörmesi ve düzeltmesi gereken bir şey olup olmadığına göre seçin!

Kopya kağıdı

Bir özel istisna (custom exception) oluşturmak için mevcut bir istisna sınıfını genişletin.

Bir denetimli istisna (checked exception) için Exception sınıfını genişletin:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

Bir denetimsiz istisna (unchecked exception) için RuntimeException sınıfını genişletin:

public class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String message) {
        super(message);
    }
}

super(message) çağrısı, hata mesajını üst sınıfa ileterek bu mesajın getMessage() aracılığıyla kullanılabilir olmasını sağlar.

Özel istisnaları diğer tüm istisnalar gibi fırlatın (throw) ve yakalayın (catch):

public void withdraw(double amount) throws InsufficientFundsException {
    if (amount > balance) {
        throw new InsufficientFundsException("Balance too low: " + balance);
    }
    balance -= amount;
}

// Using it
try {
    account.withdraw(1000);
} catch (InsufficientFundsException e) {
    System.out.println(e.getMessage());
}

Denetimli istisnalar, çağıranları bunları try-catch veya throws ile ele almaya zorlar. Denetimsiz istisnalar ise açıkça ele alma gerektirmez. Seçiminizi, hatanın çağıranların öngörmesi ve kurtulması gereken bir durum olup olmadığına göre yapın.

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int totalSeats = scanner.nextInt();
        int seatNumber = scanner.nextInt();
        
        // TODO: Verilen toplam koltuk sayısıyla bir TicketBooth oluşturun
        
        // TODO: Koltuk rezervasyonu yapmayı denemek için bir try-catch bloğu kullanın
        // - Önce TicketSoldOutException yakalayın ve "Booking failed: [exception message]" yazdırın
        // - InvalidSeatException yakalayın ve "Booking failed: [exception message]" yazdırın
        
        // TODO: try-catch bloğundan sonra, "Remaining seats: [count]" yazdırın
    }
}
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