Menu
Coddy logo textTech

Denetimli ve Denetimsiz Hatalar

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

Java'nın istisna hiyerarşisinin farklı dallara ayrıldığını gördünüz. Anlamanız gereken temel ayrım, checked (denetimli) ve unchecked (denetimsiz) istisnalar arasındadır; bu, onları kodunuzda nasıl işlemeniz gerektiğini etkiler.

Kontrollü istisnalar (Checked exceptions), derleyicinin sizi ele almaya zorladığı istisnalardır. Doğrudan Exception sınıfını genişletirler (RuntimeException üzerinden değil). Bunları ya yakalamalı ya da throws ile bildirmelisiniz:

// IOException ele alınmalıdır - bu kontrol edilen (checked) bir istisnadır
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // IOException fırlatabilir
}

// Veya yakalayın
public void readFileSafe(String path) {
    try {
        FileReader reader = new FileReader(path);
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}

Denetlenmeyen istisnalar (Unchecked exceptions) RuntimeException sınıfını genişletir. Derleyici bunları işlemenizi gerektirmez; bunlar genellikle null referansları veya geçersiz dizi erişimi gibi programlama hatalarını belirtir:

// throws deklarasyonuna gerek yoktur
public int divide(int a, int b) {
    return a / b;  // ArithmeticException fırlatabilir (unchecked)
}

String name = null;
name.length();  // NullPointerException (unchecked)

Özel istisnalar oluştururken, çağıranların bunları nasıl işlemesini istediğinize bağlı olarak üst sınıfı seçin. Çağıranın öngörmesi gereken kurtarılabilir durumlar için denetimli istisnalar (checked exceptions) kullanın. Doğru kodda oluşmaması gereken programlama hataları için denetimsiz istisnalar (unchecked exceptions) kullanın.

challenge icon

Görev

Kolay

Denetimli (checked) ve denetimsiz (unchecked) istisnalar arasındaki temel farkı gösteren bir yaş doğrulama sistemi kuralım! Her iki türden de özel istisnalar oluşturacak ve derleyicinin bunlara nasıl farklı davrandığını göreceksiniz.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • InvalidAgeException.java: Yaş doğrulama hataları için bir denetimli istisna (checked exception) oluşturun. Bu istisna doğrudan Exception sınıfını genişletmelidir, yani çağıranlar bunu ele almaya zorlanacaktır. Bir mesaj kabul eden ve bunu üst sınıfa ileten bir yapıcı (constructor) ekleyin.
  • NegativeAgeException.java: Birisi negatif bir yaş girdiğinde (doğru girdiyle olmaması gereken bir programlama hatası) kullanılacak bir denetimsiz istisna (unchecked exception) oluşturun. Bu, RuntimeException sınıfını genişletmelidir. Bir mesaj kabul eden ve bunu üst sınıfa ileten bir yapıcı ekleyin.
  • AgeVerifier.java: Her iki istisna türünü de kullanarak yaşları doğrulayan bir sınıf oluşturun. İki statik yöntem ekleyin:

    verifyAge(int age) - Bu yöntem, yaş 0'dan küçükse "Age cannot be negative: " + age mesajıyla bir NegativeAgeException (denetimsiz) fırlatmalıdır. Yaş 18'den küçükse, "Must be 18 or older: " + age mesajıyla bir InvalidAgeException (denetimli) fırlatın. Aksi takdirde, "Age " + age + " verified successfully" yazdırın. Bu yöntem denetimli bir istisna fırlattığı için, onu throws InvalidAgeException ile bildirmelisiniz.

    verifyAgeUncheckedOnly(int age) - Bu yöntem yalnızca denetimsiz istisnaları kullanır. Yaş negatifse, aynı mesaj formatıyla NegativeAgeException fırlatın. Yaş 18'den küçükse, "Too young: " + age mesajıyla bir IllegalArgumentException fırlatın. Aksi takdirde, "Age " + age + " verified (unchecked method)" yazdırın. Bu yöntemin throws bildirimine ihtiyaç duymadığına dikkat edin!

  • Main.java: Doğrulama sisteminizi bir araya getirin! Bir girdi alacaksınız: bir yaş (tamsayı).

    Önce, "=== Checked Exception Method ===" yazdırın ve girdi olarak alınan yaş ile verifyAge yöntemini çağırın. Denetimli bir istisna fırlattığı için, onu bir try-catch bloğuna almalısınız. InvalidAgeException istisnasını yakalayın ve "Checked exception caught: " + e.getMessage() yazdırın. Ayrıca NegativeAgeException istisnasını yakalayın ve "Unchecked exception caught: " + e.getMessage() yazdırın.

    Ardından boş bir satır ve "=== Unchecked Exception Method ===" yazdırın. Aynı yaş ile verifyAgeUncheckedOnly yöntemini çağırın. Bu yöntem istisna fırlatabilse de, onları yakalamaya zorlanmazsınız. Ancak, hataları düzgün bir şekilde ele almak için yine de bir try-catch bloğuna alın. NegativeAgeException istisnasını yakalayın ve "Runtime exception caught: " + e.getMessage() yazdırın. IllegalArgumentException istisnasını yakalayın ve "Illegal argument caught: " + e.getMessage() yazdırın.

Bir girdi alacaksınız: doğrulanacak yaşı temsil eden bir tamsayı.

Temel farka dikkat edin: denetimli istisnaya sahip yöntem bir throws bildirimi gerektirir ve çağıranları bunu ele almaya zorlar; denetimsiz yöntem ise herhangi bir istisna işleme olmasa bile sorunsuz derlenir. Bu, Java'daki denetimli ve denetimsiz istisnalar arasındaki temel ayrımdır!

Kopya kağıdı

Java istisnaları, derleyicinin bunların işlenmesini nasıl zorunlu kıldığını belirleyen checked (denetimli) ve unchecked (denetimsiz) istisnalar olarak ikiye ayrılır.

Checked istisnalar doğrudan Exception sınıfını genişletir (RuntimeException üzerinden değil). Derleyici, sizi bunları yakalamaya veya throws ile bildirmeye zorlar:

// throws ile bildirilmelidir
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);
}

// Veya yakalanmalıdır
public void readFileSafe(String path) {
    try {
        FileReader reader = new FileReader(path);
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}

Unchecked istisnalar RuntimeException sınıfını genişletir. Derleyici bunları işlemenizi gerektirmez. Genellikle programlama hatalarını belirtirler:

// throws bildirimi gerekmez
public int divide(int a, int b) {
    return a / b;  // ArithmeticException fırlatabilir (unchecked)
}

String name = null;
name.length();  // NullPointerException (unchecked)

Özel istisnalar oluştururken, çağıranların bunları nasıl işlemesi gerektiğine bağlı olarak üst sınıfı seçin:

  • Çağıranın öngörmesi gereken kurtarılabilir durumlar için checked istisnaları (Exception sınıfını genişletin) kullanın
  • Doğru kodda oluşmaması gereken programlama hataları için unchecked istisnaları (RuntimeException sınıfını genişletin) kullanın

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int age = scanner.nextInt();
        
        // TODO: Kontrollü istisna (checked exception) yöntemini test edin
        // Yazdır: "=== Checked Exception Method ==="
        // Bir try-catch bloğu içinde AgeVerifier.verifyAge(age) metodunu çağırın
        // - InvalidAgeException yakala: "Checked exception caught: [mesaj]" yazdır
        // - NegativeAgeException yakala: "Unchecked exception caught: [mesaj]" yazdır
        
        
        // TODO: Boş bir satır yazdırın, ardından "=== Unchecked Exception Method ===" yazdırın
        // Bir try-catch bloğu içinde AgeVerifier.verifyAgeUncheckedOnly(age) metodunu çağırın
        // - NegativeAgeException yakala: "Runtime exception caught: [mesaj]" yazdır
        // - IllegalArgumentException yakala: "Illegal argument caught: [mesaj]" yazdır
        
    }
}
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