Bölüm 6: Hata Ayıklama ve İstisnalar

Java ile Nesne Yönelimli Programlama
İstisna kavramıtry ve catchÇoklu catchfinallytry-with-resourcesİç içe try İstisna hiyerarşisiKontrol edilen / edilmeyenthrow ve throwsYaygın istisna sınıflarıErrorÖzel istisnalarİzleme listesi
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Kavram

İstisnayı (exception) tanımlamak; derleme, çalışma zamanı ve mantık hatalarını ayırt etmek.

Yakalama

try, catch, finally ve try-with-resources ile istisnaları ele almak; akışı adım adım izlemek.

Hiyerarşi

Throwable, Error, Exception, RuntimeException ilişkisini ve catch sırasının önemini açıklamak.

Türler

Kontrol edilen (checked) ve kontrol edilmeyen (unchecked) istisnaları ayırmak; “ele al veya bildir” kuralını uygulamak.

Fırlatma

throw ile istisna fırlatmak, throws ile bildirmek; istisnanın çağrı yığınında yayılımını izlemek.

Uygulama

Yaygın istisna sınıflarını tanımak, özel istisna sınıfı yazmak ve izleme listesini (stack trace) okumak.

İstisna Kavramı

İstisna Nedir?

  • İstisna (exception): program çalışırken ortaya çıkan, programın normal akışını bozan beklenmeyen bir durumdur.
  • Örnek: açılmak istenen dosyanın bulunamaması, sıfıra bölme, dizinin dışına erişim, null bir referansın kullanılması.
  • İstisnalar Java çalışma zamanı sistemi (JVM) tarafından otomatik olarak ya da programcı tarafından kodla (throw) oluşturulabilir.
  • Java'da istisna bir nesnedir: türünü, mesajını ve nerede oluştuğunu taşır.
  • İstisna mekanizması, programcıya anormal durumlarla düzenli bir şekilde başa çıkma şansı verir.
Java bir istisnayla karşılaştığında kabaca şunu der: “Pes ettim, şu an ne yapacağımı bilmiyorum. Sen hallet!”
Benzetme

Garson mutfakta yemeğin bittiğini öğrenir. Kendisi çözemez; durumu yöneticiye bildirir. Yönetici ya çözer (başka yemek önerir) ya da durumu bir üste iletir.

İstisna Kavramı

Üç Tür Hata

TürNe zaman?Kim yakalar?Örnek
Derleme hatası
(compile-time error)
Program derlenirkenjavac; program hiç çalışmazNoktalı virgül unutmak, int x = "a";
Çalışma zamanı hatası
(runtime error) → istisna
Program çalışırkenJVM bir istisna nesnesi fırlatır10 / 0, dizi[5] (3 elemanlı dizide)
Mantık hatası
(logic error)
Program çalışır ama sonuç yanlışHiçbiri; testlerle bulunurOrtalamada / 2 yerine / 3 yazmak

Bu bölümün konusu ortadaki satırdır: istisnalar. Hata ayıklama (debugging) ise üç türün de nedenini bulup düzeltme işidir; istisna mekanizması ve izleme listesi bunun en güçlü araçlarındandır.

İstisna Kavramı

Yakalanmayan İstisna: Program Çöker

public class Cokus {
  public static void main(String[] args) {
    int pay = 10, payda = 0;
    System.out.println("Başla");
    int sonuc = pay / payda;
    System.out.println("Sonuç: " + sonuc);
    System.out.println("Bitti");
  }
}
Çıktı
Başla
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Cokus.main(Cokus.java:5)
  • 5. satırda tamsayı sıfıra bölünür; JVM bir ArithmeticException nesnesi fırlatır.
  • Kimse yakalamadığı için program sonlanır: “Sonuç” ve “Bitti” hiç yazılmaz.
  • JVM, istisnanın türünü, mesajını ve yerini (sınıf, metot, satır) yazdırır.

İstisna Kavramı

İstisnayla Başa Çıkmanın İki Yolu

1) Ele almak (handle)

Metot, istisna oluşturabilecek kodu try içine alır ve catch ile durumu kendisi çözer.

Örnek: dosya okuma metodu, dosya bulunamazsa (FileNotFoundException) kullanıcıya mesaj gösterip varsayılan ayarlarla devam eder.

2) Çağıranın sorunu yapmak (declare)

Metot istisnayı ele almaz; imzasında throws ile bildirir. İstisna, metodu çağıran kodun sorunu olur.

Çağıran kod da aynı seçimle karşılaşır: ya ele alır ya da bir üste iletir.

Hangi yol? İstisnayı anlamlı biçimde çözebilecek yer ele almalıdır. Örneğin dosya adını kullanıcıdan alan kod, “dosya yok” durumunda yeniden sorabilir; düşük seviyeli okuma metodu ise bunu bilemez.

İstisna Kavramı

“Ters Giden Bir Şey”: Dönüş Kodu ile

public static int indexOf(String[] isimler, String isim) {
  for (int i = 0; i < isimler.length; i++) {
    if (isimler[i].equals(isim)) {
      return i;
    }
  }
  return -1;
}
// main içinde
String[] isimler = {"Ali", "Ayşe", "Can"};
System.out.println(indexOf(isimler, "Can"));
int k = indexOf(isimler, "Ece");   // k = -1
System.out.println(isimler[k]);
Çıktı
2
java.lang.ArrayIndexOutOfBoundsException:
  Index -1 out of bounds for length 3
  • İstisnalar, bir programın “bir şeyin ters gittiğini” bildirmesi için kullanılır.
  • Ama “ters gitmek” özneldir: aranan ismin bulunamaması hata mıdır, olağan bir sonuç mu?
  • Bu metot, eşleşme bulamazsa istisna fırlatmak yerine -1 döndürür.
  • Çağıran, -1'i kontrol etmeyi unutursa hata başka bir yerde, isimler[-1] erişiminde ortaya çıkar (soldaki çıktı).

İstisna Kavramı

Öneri: İstisnaları Kullanın

public static int bul(String[] isimler, String isim) {
  for (int i = 0; i < isimler.length; i++) {
    if (isimler[i].equals(isim)) {
      return i;
    }
  }
  throw new IllegalArgumentException("Bulunamadı: " + isim);
}
// main içinde
try {
  System.out.println(bul(isimler, "Ece"));
} catch (IllegalArgumentException e) {
  System.out.println("Hata: " + e.getMessage());
}
Çıktı
Hata: Bulunamadı: Ece
  • Genellikle -1 gibi özel dönüş kodlarından kaçınılmalı, Java'nın istisna mekanizması tercih edilmelidir.
  • İstisna, hata durumunu açık ve etkili biçimde ele almanın yoludur.

İstisnaların yararı

  • Açık ve tutarlı hata işleme; hata normal sonuçla karışmaz
  • Okunabilirlik artar, hata ayıklama kolaylaşır
  • Kodun güvenilirliği artar

try ve catch

try ve catch İfadeleri

try {
  // Potansiyel hata içeren kodlar
  int sonuc = 10 / 0; // Hata: ArithmeticException
} catch (ArithmeticException e) {
  // Hata durumuyla başa çıkma
  System.out.println("hata oluştu: " + e.getMessage());
}
Çıktı
hata oluştu: / by zero
  • Hata yönetiminin temel yapısıdır.
  • try bloğu: potansiyel hata içeren kodlar.
  • catch bloğu: try içinde belirtilen türde bir istisna oluşursa çalışır ve onu ele alır.
  • catch (ArithmeticException e): e, fırlatılan istisna nesnesine referanstır (bir parametre gibi).
  • İstisna oluşursa try'ın kalan satırları atlanır; istisna oluşmazsa catch hiç çalışmaz.
  • catch'ten sonra program normal akışına devam eder.

try ve catch · Kodu adım adım çalıştır

try-catch Akışı: Adım Adım

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

Değişkenler oluşur. payda sıfır: sorun yaklaşıyor.

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

try dışındaki normal kod çalışır.

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

try bloğuna girildi; ilk satır sorunsuz çalışır.

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

10 / 0: JVM bir ArithmeticException nesnesi oluşturur ve fırlatır. Atama yapılmaz.

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)✓println("Hata: " + …)println("Bitti")

Tür eşleşir: catch çalışır, e istisna nesnesini gösterir. “Sonuç” satırı atlandı.

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

e.getMessage() → "/ by zero".

println("Bölme öncesi")sonuc = pay / paydaprintln("Sonuç: " + …)catch (ArithmeticException e)println("Hata: " + …)println("Bitti")

Program çökmedi: catch'ten sonra normal akış devam eder.

public class BolmeOrnegi {
  public static void main(String[] args) {
    int pay = 10, payda = 0;
    System.out.println("Başla");
    try {
      System.out.println("Bölme öncesi");
      int sonuc = pay / payda;
      System.out.println("Sonuç: " + sonuc);
    } catch (ArithmeticException e) {
      System.out.println("Hata: " + e.getMessage());
    }
    System.out.println("Bitti");
  }
}

try ve catch

İstisna Nesnesinden Bilgi Almak

try {
  int[] dizi = new int[3];
  dizi[5] = 7;
} catch (ArrayIndexOutOfBoundsException e) {
  System.out.println(e.getMessage());
  System.out.println(e);
  System.out.println(e.getClass().getSimpleName());
  e.printStackTrace();
}
Çıktı
Index 5 out of bounds for length 3
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
    at IstisnaNesnesi.main(IstisnaNesnesi.java:5)
MetotNe verir?
getMessage()Yalnızca açıklama mesajı (yoksa null)
toString()Tam sınıf adı + “: ” + mesaj; println(e) bunu kullanır
getClass()İstisnanın gerçek sınıfı
printStackTrace()toString() + izleme listesi; System.err'e yazar
getCause()Bu istisnaya yol açan başka istisna (varsa)

try ve catch

Çoklu catch Bloğu

try {
  // Potansiyel hata içeren kodlar
} catch (ArithmeticException e) {
  // ArithmeticException ile başa çıkma
} catch (NullPointerException e) {
  // NullPointerException ile başa çıkma
} catch (Exception e) {
  // Diğer hata türleri için genel durum
}
  • Bir kod bloğunda birden çok türde istisna oluşabilir.
  • Her hata türü için ayrı bir catch bloğu eklenir; her blok o türe özgü tepkiyi içerir.
  • İstisna fırlatıldığında catch blokları yukarıdan aşağıya sırayla denenir; eşleşen ilk blok çalışır, diğerleri atlanır.
  • “Eşleşmek”: fırlatılan nesne, catch'teki türün kendisi veya alt sınıfıdır (instanceof mantığı).
  • Son sıradaki catch (Exception e) geri kalan tüm istisnaları yakalayan genel durumdur.

try ve catch

Zincirleme catch Blokları: Sıra Önemlidir

✗ Genel tür önce

try {
  int sonuc = 10 / 0;
} catch (Exception e) {
  System.out.println("Genel hata");
} catch (ArithmeticException e) {
  System.out.println("Aritmetik hata");
}
SiraHatasi.java:7: error: exception ArithmeticException
    has already been caught
  • catch türleri arasında kalıtım ilişkisi varsa sıralama önemlidir: alt sınıflar, üst sınıflardan önce gelmelidir.
  • ArithmeticException bir Exception'dır; ilk blok onu zaten yakalar, ikinci blok asla çalışamaz. Derleyici buna izin vermez.
  • Kalıtım ilişkisi olmayan türlerin (ArithmeticException, NullPointerException) sırası önemli değildir.

✓ Özelden genele

} catch (ArithmeticException e) {
  System.out.println("Aritmetik hata");
} catch (Exception e) {
  System.out.println("Genel hata");
}

try ve catch · Kodu adım adım çalıştır

Hangi catch Çalışır?

NumberFormatException1. catch: NumberFormat2. catch: Arithmetic3. catch: ArrayIndexOutOfBoundsfinally

1. çağrı: parseInt("abc") → NumberFormatException. Bölme satırı atlanır.

NumberFormatException1. catch: NumberFormat✓2. catch: Arithmetic3. catch: ArrayIndexOutOfBoundsfinally

İlk catch eşleşir ve çalışır; diğer catch'lere bakılmaz.

NumberFormatException1. catch: NumberFormat✓2. catch: Arithmetic3. catch: ArrayIndexOutOfBoundsfinally

Ardından finally.

ArithmeticException1. catch: NumberFormat2. catch: Arithmetic3. catch: ArrayIndexOutOfBoundsfinally

2. çağrı: 10 / 0 → ArithmeticException.

ArithmeticException1. catch: NumberFormat✗2. catch: Arithmetic✓3. catch: ArrayIndexOutOfBoundsfinally

1. catch eşleşmez (✗), 2. catch eşleşir (✓).

ArrayIndexOutOfBoundsException1. catch: NumberFormat2. catch: Arithmetic3. catch: ArrayIndexOutOfBoundsfinally

3. çağrı: dizinin tek elemanı var; girdi[1] → ArrayIndexOutOfBoundsException.

ArrayIndexOutOfBoundsException1. catch: NumberFormat✗2. catch: Arithmetic✗3. catch: ArrayIndexOutOfBounds✓finally

İlk iki catch eşleşmez, üçüncüsü eşleşir; sonra finally.

static void bol(String[] girdi) {
  try {
    int x = Integer.parseInt(girdi[0]);
    int y = Integer.parseInt(girdi[1]);
    System.out.println("Sonuç: " + (x / y));
  } catch (NumberFormatException e) {
    System.out.println("Sayı değil: " + e.getMessage());
  } catch (ArithmeticException e) {
    System.out.println("Sıfır: " + e.getMessage());
  } catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Eksik: " + e.getMessage());
  } finally {
    System.out.println("finally çalıştı");
  }
}
// main içinde
bol(new String[] {"10", "abc"});
bol(new String[] {"10", "0"});
bol(new String[] {"10"});

try ve catch

Tek catch, Birden Çok Tür (Java 7+)

try {
  Object o = "Merhaba";
  Integer i = (Integer) o;
} catch (ClassCastException
    | NullPointerException e) {
  System.out.println("Tür veya null hatası: "
    + e.getClass().getSimpleName());
}
Çıktı
Tür veya null hatası: ClassCastException
  • Tepki aynıysa türler | ile birleştirilir; kod tekrarı azalır.
  • Bu blokta e final sayılır; yeni değer atanamaz.

✗ Alt ve üst sınıf birlikte yazılamaz

} catch (FileNotFoundException
    | IOException e) {
error: Alternatives in a multi-catch statement
  cannot be related by subclassing
  Alternative FileNotFoundException is a
  subclass of alternative IOException
Çözüm: yalnızca üst türü yazın: catch (IOException e). Alt tür zaten onun içindedir.

finally

finally Bloğu

try {
  // Potansiyel hata içeren kodlar
} catch (Exception e) {
  // Diğer hata türleri için genel durum
} finally {
  // Her durumda çalıştırılacak kodlar
}
  • try ve catch bloklarının ardından eklenir.
  • İstisna olsun veya olmasın, yakalansın veya yakalanmasın, her durumda çalışır.
  • try veya catch içinde return olsa bile, metottan çıkmadan önce çalışır.
  • Kodun belirli adımlarının çalışmasını güvence altına alır: dosya, ağ ve veritabanı bağlantılarını kapatmak gibi kaynak yönetimi ve temizlik işleri.
  • try'dan sonra en az bir catch veya finally gelmelidir; try { } finally { } geçerlidir.
  • Tek istisna: System.exit() JVM'i hemen durdurur; finally çalışmaz.

finally · Kodu adım adım çalıştır

finally ve return: Adım Adım

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

println'dan önce argümanı hesaplanmalı: bol(10, 2) çağrılır.

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

try bloğu başlar.

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

Bölme başarılı: s = 5.

try { … }catch (ArithmeticException e)finally { … }bekleyen dönüş değeri: 5

return s: dönüş değeri 5 hazırlanır, ama metot hemen bitmez…

try { … }catch (ArithmeticException e)finally { … }bekleyen dönüş değeri: 5

…önce finally çalışır. catch atlandı (istisna yok).

try { … }catch (ArithmeticException e)finally { … }bekleyen dönüş değeri: 5

Şimdi 5 döner ve yazdırılır.

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

İkinci çağrı: bol(10, 0).

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

try başlar.

try { … }catch (ArithmeticException e)finally { … }dönüş değeri henüz yok

10 / 0 → istisna! try'ın kalanı (“try bitti”, return s) atlanır.

try { … }catch (ArithmeticException e)✓finally { … }dönüş değeri henüz yok

catch eşleşir ve mesajı yazar.

try { … }catch (ArithmeticException e)✓finally { … }bekleyen dönüş değeri: -1

return -1: değer hazır, ama yine önce finally.

try { … }catch (ArithmeticException e)✓finally { … }bekleyen dönüş değeri: -1

finally bu kez de çalışır.

try { … }catch (ArithmeticException e)✓finally { … }bekleyen dönüş değeri: -1

-1 döner. Sonuç: finally iki durumda da çalıştı.

static int bol(int a, int b) {
  try {
    System.out.println("try başladı");
    int s = a / b;
    System.out.println("try bitti");
    return s;
  } catch (ArithmeticException e) {
    System.out.println("catch: " + e.getMessage());
    return -1;
  } finally {
    System.out.println("finally");
  }
}
public static void main(String[] args) {
  System.out.println("Sonuç = " + bol(10, 2));
  System.out.println("Sonuç = " + bol(10, 0));
}

finally

try-with-resources (Java 7+)

class Kaynak implements AutoCloseable {
  private String ad;
  Kaynak(String ad) {
    this.ad = ad;
    System.out.println(ad + " açıldı");
  }
  void kullan(int x) {
    System.out.println(ad + " kullanılıyor");
    int s = 10 / x;
  }
  @Override
  public void close() {
    System.out.println(ad + " kapatıldı");
  }
}
try (Kaynak k = new Kaynak("dosya")) {
  k.kullan(0);
} catch (ArithmeticException e) {
  System.out.println("Hata: " + e.getMessage());
}
Çıktı
dosya açıldı
dosya kullanılıyor
dosya kapatıldı
Hata: / by zero
  • try (...) içinde açılan kaynak, blok bitince otomatik kapatılır (close()); istisna olsa bile.
  • Kaynak catch'ten önce kapanır. Kaynak sınıfı AutoCloseable arayüzünü uygulamalıdır (dosya ve veritabanı sınıfları uygular).
  • Kaynak kapatmak için finally yazmanın modern ve güvenli yolu budur.

finally

İç İçe try Blokları

try {
  // Dıştaki try bloğu
  try {
    // İçteki try bloğu
    // Potansiyel hata içeren kodlar
  } catch (Exception e) {
    // İçteki catch bloğu
  } finally {
    // İçteki finally bloğu
  }
} catch (Exception e) {
  // Dıştaki catch bloğu
} finally {
  // Dıştaki finally bloğu
}

Bir try bloğu içinde başka bir try bloğu bulunabilir. İçteki try'da bir istisna oluşursa:

  1. İçteki try'ın catch'lerinde uygun bir catch varsa o çalışır.
  2. Yoksa istisna dışa doğru ilerler; ilk uygun catch bulunur ve çalışır.
  3. Hiçbir catch eşleşmezse istisna metottan çıkar; sonunda kimse yakalamazsa JVM'in varsayılan işleyicisi programı sonlandırır.
  4. Her durumda, istisnanın geçtiği her seviyedeki finally (varsa) çalışır.

finally · Kodu adım adım çalıştır

İç İçe try: İstisna Dışa Doğru İlerler

dış try {iç try { … s.length() }iç catch (ArithmeticException)iç finallyprintln("Dış try devam")dış catch (NullPointerException)dış finallyprintln("Program sürüyor")

Dış try başlar.

dış try {iç try { … s.length() }iç catch (ArithmeticException)iç finallyprintln("Dış try devam")dış catch (NullPointerException)dış finallyprintln("Program sürüyor")

İç try başlar; s = null.

dış try {iç try { … s.length() }iç catch (ArithmeticException)iç finallyprintln("Dış try devam")dış catch (NullPointerException)dış finallyprintln("Program sürüyor")

null üzerinde metot çağrısı → NullPointerException.

dış try {iç try { … s.length() }iç catch (ArithmeticException)✗iç finallyprintln("Dış try devam")dış catch (NullPointerException)dış finallyprintln("Program sürüyor")

İç catch yalnızca ArithmeticException yakalar: eşleşmez.

dış try {iç try { … s.length() }iç catch (ArithmeticException)✗iç finallyprintln("Dış try devam")dış catch (NullPointerException)dış finallyprintln("Program sürüyor")

İstisna dışarı çıkmadan önce iç finally çalışır.

dış try {iç try { … s.length() }iç catch (ArithmeticException)✗iç finallyprintln("Dış try devam")dış catch (NullPointerException)✓dış finallyprintln("Program sürüyor")

İstisna dış seviyeye geçti; “Dış try devam” atlandı. Dış catch eşleşir.

dış try {iç try { … s.length() }iç catch (ArithmeticException)✗iç finallyprintln("Dış try devam")dış catch (NullPointerException)✓dış finallyprintln("Program sürüyor")

Dış finally çalışır.

dış try {iç try { … s.length() }iç catch (ArithmeticException)✗iç finallyprintln("Dış try devam")dış catch (NullPointerException)✓dış finallyprintln("Program sürüyor")

İstisna ele alındı; program normal devam eder.

public static void main(String[] args) {
  try {
    System.out.println("Dış try");
    try {
      System.out.println("İç try");
      String s = null;
      System.out.println(s.length());
    } catch (ArithmeticException e) {
      System.out.println("İç catch");
    } finally {
      System.out.println("İç finally");
    }
    System.out.println("Dış try devam");
  } catch (NullPointerException e) {
    System.out.println("Dış catch: NPE");
  } finally {
    System.out.println("Dış finally");
  }
  System.out.println("Program sürüyor");
}

İstisna Hiyerarşisi

İstisnalar Hiyerarşisi

  • Java'da istisna sınıfları bir sınıf hiyerarşisi içindedir.
  • Throwable sınıfı, fırlatılabilen her şeyin atasıdır: yalnızca Throwable ve alt sınıflarının nesneleri throw edilebilir ve catch ile yakalanabilir.
  • Throwable'ın iki doğrudan alt sınıfı vardır: Error ve Exception.
  • Bir catch bloğu, yazılan türü ve tüm alt sınıflarını yakalar (kalıtımın doğal sonucu).
  • Java, yeni özel istisna sınıfları oluşturmayı destekler: uygulamaya özgü durumlara uyan sınıflar bu hiyerarşiye eklenir.
Neden hiyerarşi?

Aynı aileden istisnalar tek bir üst türle yakalanabilir: catch (IOException e) hem FileNotFoundException'ı hem de diğer giriş/çıkış hatalarını yakalar.

İstisna Hiyerarşisi

İstisna Sınıf Ağacı

ThrowableErrorExceptionOutOfMemoryErrorStackOverflowErrorAssertionErrorciddi sistem sorunlarıdiğer alt sınıflar (kontrol edilen)IOExceptionFileNotFoundExceptionSQLExceptionClassNotFoundExceptionParseExceptionInterruptedExceptionRuntimeExceptionArithmeticExceptionNullPointerExceptionClassCastExceptionIllegalArgumentExceptionNumberFormatExceptionIndexOutOfBoundsExceptionArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsException
kontrol edilen (checked)kontrol edilmeyen: RuntimeException ve alt sınıflarıkontrol edilmeyen: Error ve alt sınıfları

İstisna Hiyerarşisi

Error ve Exception

Error

  • Programın kurtarılamayacak ciddi bir sorunla karşılaştığını belirtir.
  • Bu durumlarla başa çıkmak çoğunlukla mümkün değildir; genellikle programın sonlanmasına yol açar.
  • Örnek: program belleğinin tükenmesi (OutOfMemoryError), çağrı yığınının taşması, disk sürücüsünün “kaybolması” gibi aşırı durumlar.
  • Uygulama kodunda yakalanması önerilmez.

Exception

  • Programın öngörebileceği ve çoğu zaman kurtarabileceği durumlar.
  • Dosya yok, ağ koptu, geçersiz girdi, null referans…
  • try-catch ile ele alınması beklenen türdür.
  • Alt sınıfı RuntimeException, çoğunlukla programcı hatalarını temsil eder.

Her ikisi de Throwable'dan türer; bu yüzden ikisi de fırlatılabilir. Ama “ele alınmalı” olan, Exception ailesidir.

İstisna Türleri

İstisna Türleri

Kontrol edilen (checked exceptions)

Derleme zamanında derleyici denetler; programcı ele almak ya da bildirmek zorundadır. Ortaya çıkabileceği önceden bilinen durumlar.

Kontrol edilmeyen (unchecked exceptions)

Derleme zamanında denetlenmez; çalışma zamanında ortaya çıkar. RuntimeException, Error ve alt sınıfları.

İstisna türleriKullanıcı tanımlı (user-defined)Yerleşik (built-in)Kontrol edilen (checked)Kontrol edilmeyen (unchecked)ClassNotFoundExceptionInterruptedExceptionIOExceptionInstantiationExceptionSQLExceptionFileNotFoundExceptionArithmeticExceptionClassCastExceptionNullPointerExceptionArrayIndexOutOfBoundsExceptionArrayStoreExceptionIllegalThreadStateException… extends Exception→ kontrol edilen… extends RuntimeException→ kontrol edilmeyen

İstisna Türleri

Kontrol Edilen İstisna (Checked)

  • Kod tarafından ele alınması veya bildirilmesi gerekir: “catch or declare” (yakala ya da bildir) kuralı.
  • Metodun başında throws ile belirtilmeli veya try-catch içinde ele alınmalıdır.
  • Exception'dan türer ama RuntimeException'dan türemez.
  • Bu kural derleme zamanında denetlenir: uyulmazsa program derlenmez.
  • Örnek: var olmayan bir dosyayı okumaya çalışmak. Program ne kadar doğru yazılsa da dosya silinmiş olabilir; bu yüzden derleyici bir plan ister.

✗ Ne ele alınmış ne bildirilmiş

public void dosyaOku() {
  FileReader okuyucu = new FileReader("veri.txt");
}
error: unreported exception FileNotFoundException;
  must be caught or declared to be thrown

✓ throws ile bildirilmiş

public void dosyaOku() throws FileNotFoundException {
  // Dosya okuma kodu
  FileReader okuyucu = new FileReader("veri.txt");
}

İstisna Türleri

Kontrol Edilen İstisnayı Ele Almak

public static void dosyaOku2() {
  try {
    FileReader okuyucu = new FileReader("veri.txt");
    // Dosya okuma kodu
  } catch (FileNotFoundException e) {
    // Kontrol edilen istisna burada ele alınıyor
    System.err.println("Dosya bulunamadı: " + e.getMessage());
    // Gerekirse istisna tekrar fırlatılabilir:
    // throw e;
  }
}
Çıktı (Windows; Linux'ta: No such file or directory)
Dosya bulunamadı: veri.txt (The system cannot find the file specified)
  • Bu sürümde metot istisnayı kendisi yakalar; imzasında throws yoktur. Çağıran kod hiçbir şey yapmak zorunda değildir.
  • System.err: hata çıktısı akışı. Konsolda çoğu IDE bunu kırmızı gösterir.
  • Mesaj, işletim sisteminden gelir; Windows ve Linux'ta farklıdır.
  • throw e;: yakalanan istisna, gerekirse (örneğin kayıt tuttuktan sonra) tekrar fırlatılabilir. O zaman metot yine throws FileNotFoundException bildirmelidir.

İstisna Türleri

Kontrol Edilmeyen İstisna (Unchecked)

  • Ele alınması veya bildirilmesi zorunlu olmayan istisna türleridir.
  • Genellikle mantık hataları veya programcı hataları sonucu ortaya çıkar: sıfıra bölme, null kullanımı, dizi sınırını aşma.
  • throws ile belirtilmesi veya try-catch içine alınması zorunlu değildir; derleyici sessiz kalır.
  • RuntimeException veya Error sınıflarından türer.
  • Doğru çözüm çoğu zaman yakalamak değil, önlemektir: bölmeden önce paydayı, kullanmadan önce null'ı denetlemek.
public void bolmeIslemi(int pay, int payda) {
  // Kontrol edilmeyen istisna: ArithmeticException
  int sonuc = pay / payda;
}

Derlenir, throws gerekmez. payda == 0 olursa çalışma zamanında istisna oluşur.

public void bolmeIslemi(int pay, int payda) {
  if (payda == 0) {   // önleme
    System.out.println("Payda sıfır olamaz");
    return;
  }
  int sonuc = pay / payda;
}

İstisna Türleri

Kontrol Edilen, Kontrol Edilmeyen, Error

Kontrol edilenKontrol edilmeyenError
Üst sınıfException (RuntimeException hariç)RuntimeExceptionError
Derleyici denetler mi?Evet: ele al veya bildirHayırHayır
Tipik nedenProgramın dışındaki koşullar (dosya, ağ, veritabanı)Programcı hatası (null, sınır, bölme)JVM / sistem sorunu
Ne yapılmalı?Yakala ve kurtar, ya da throws ile iletKodu düzelt, girdiyi denetleGenellikle yakalama; programı düzgün sonlandır
ÖrneklerIOException, SQLException, ClassNotFoundExceptionNullPointerException, ArithmeticExceptionOutOfMemoryError, StackOverflowError

İstisna Fırlatma

İstisna Fırlatma (Throwing an Exception)

  • Java çalışma zamanı beklenmeyen bir durumla karşılaştığında, üst seviyedeki kodlara bildirmek için bir istisna nesnesi oluşturur ve fırlatır.
  • Programcı da aynısını throw anahtar kelimesiyle yapabilir.
  • İstisna, normal program akışını değiştirir: throw'dan sonraki satırlar çalışmaz; denetim uygun catch'e geçer.
  • Fırlatılabilen birçok tür vardır: IOException, NullPointerException, IllegalArgumentException, kendi özel sınıflarınız…
  • Fırlatılan istisna, çağıran kod tarafından try-catch ile yakalanabilir. Hiçbir yerde ele alınmazsa JVM programı sonlandırır ve neyin yanlış gittiğini, nerede olduğunu bildirir.

Söz dizimi

throw new Exception("Bu bir istisna durumu!");

new ile istisna nesnesi oluşturulur (yapıcıya mesaj verilir), throw ile fırlatılır.

try {
  throw new Exception("Bu bir istisna durumu!");
} catch (Exception e) {
  System.out.println(e);
}
Çıktı
java.lang.Exception: Bu bir istisna durumu!

İstisna Fırlatma

Durumu En İyi Anlatan Türü Fırlatın

class CustomException extends Exception {
  public CustomException(String mesaj) {
    super(mesaj);
  }
}
public static void kontrolEt(int deger)
    throws CustomException {
  if (deger < 0) {
    // Belirli bir durumu kontrol et ve istisna fırlat
    throw new CustomException("Değer negatif olamaz!");
  }
  // Değer pozitifse, normal işlem devam eder
  System.out.println("Değer uygun: " + deger);
}
// main içinde
try {
  kontrolEt(5);
  kontrolEt(-3);
  kontrolEt(8);
} catch (CustomException e) {
  System.out.println("Yakalandı: " + e.getMessage());
}
Çıktı
Değer uygun: 5
Yakalandı: Değer negatif olamaz!
  • İstisna türü seçilirken durumu en iyi temsil eden sınıf seçilmelidir.
  • Özel senaryolar için özel istisna sınıfları oluşturulabilir (ayrıntısı ileride).
  • CustomException bir Exception alt sınıfıdır: kontrol edilen bir istisnadır. Bu yüzden metot imzasında throws CustomException şarttır.
  • kontrolEt(-3) fırlattığı anda try'ın kalanı atlanır: kontrolEt(8) hiç çağrılmaz.

İstisna Fırlatma

throw ve throws Farkı

throwthrows
GöreviBir istisnayı fırlatır (şimdi)Metodun fırlatabileceği istisnaları bildirir (ileride olabilir)
YeriMetot gövdesinde, bir deyim olarakMetot imzasında, parametrelerden sonra
ArdındanTek bir nesne: throw new X("…");Bir veya daha çok tür: throws X, Y
Örnekthrow new ArithmeticException("Sıfıra bölme");void bol(int x, int y) throws ArithmeticException

✗ throws gövdede kullanılmaz

if (x < 0) {
  throws new IllegalArgumentException("negatif");
}
error: illegal start of expression

✗ Kontrol edilen istisna, bildirilmeden fırlatılmış

static void f(int x) {
  if (x < 0) throw new Exception("negatif");
}
error: unreported exception Exception;
  must be caught or declared to be thrown

İstisna Fırlatma

İstisna Fırlatan Metotları Çağırmak

Dosya okuma metodu

public void dosyaOku() throws FileNotFoundException {
  // Dosya okuma kodu
}

1) Çağıran ele alır (tercih edilen)

try {
  dosyaOku();
} catch (FileNotFoundException e) {
  // Dosya bulunamadı durumuyla başa çıkma kodu
  System.err.println("Dosya bulunamadı: " + e.getMessage());
}

2) Çağıran da bildirir (iletir)

public void raporHazirla() throws FileNotFoundException {
  dosyaOku();
}
  • Metot çağırırken, metodun imzasında belirtilen istisnalar dikkate alınmalı ve uygun bir strateji seçilmelidir.
  • Çağrı, uygun try-catch bloğunun içine yazılır.
  • Ya da çağıran metot da imzasında throws ile aynı türü bildirir; sorun bir üst seviyeye geçer. Bu, sorunu yalnızca ertelediği için yakalamaktan daha az tercih edilir.
  • main bile throws yazabilir; o zaman yakalanmayan istisna programı sonlandırır.

İstisna Fırlatma · Kodu adım adım çalıştır

Yayılım: İstisna Çağrı Yığınında İner

Çağrı yığını (call stack)main()

main, try içinde hesapla(10)'u çağırır.

Çağrı yığını (call stack)main()hesapla(10)

Yığına hesapla çerçevesi eklendi.

Çağrı yığını (call stack)main()hesapla(10)

hesapla, bol(10, 0)'ı çağırır.

Çağrı yığını (call stack)main()hesapla(10)bol(10, 0)

Yığının tepesinde artık bol var.

Çağrı yığını (call stack)main()hesapla(10)bol(10, 0)ArithmeticException/ by zero

10 / 0: istisna bol'da doğdu. bol'da try yok → bol'un kalanı çalışmaz, çerçevesi atılır.

Çağrı yığını (call stack)main()hesapla(10)ArithmeticException/ by zerobol(10, 0)

İstisna çağıran yere, hesapla'ya geçti. Burada da try yok → “hesapla bitti” atlanır, çerçeve atılır.

Çağrı yığını (call stack)main()ArithmeticException/ by zerohesapla(10)bol(10, 0)

İstisna main'e ulaştı. Çağrı bir try içinde: uygun catch aranır. “Sonuç” satırı atlanır.

Çağrı yığını (call stack)main()hesapla(10)bol(10, 0)

catch eşleşti: istisna yakalandı, yayılım durdu.

Çağrı yığını (call stack)main()hesapla(10)bol(10, 0)

Program normal biçimde biter. Kimse yakalamasaydı JVM programı sonlandırırdı.

static int bol(int a, int b) {
  System.out.println("bol başladı");
  int s = a / b;
  System.out.println("bol bitti");
  return s;
}
static int hesapla(int x) {
  System.out.println("hesapla başladı");
  int r = bol(x, 0);
  System.out.println("hesapla bitti");
  return r;
}
public static void main(String[] args) {
  try {
    int sonuc = hesapla(10);
    System.out.println("Sonuç: " + sonuc);
  } catch (ArithmeticException e) {
    System.out.println("main: " + e.getMessage());
  }
  System.out.println("Program bitti");
}

İstisna Fırlatma

JVM İstisnayı Nasıl Ele Alır?

  1. JVM (veya throw) bir istisna nesnesi oluşturur: türü, mesajı ve oluştuğu yerin izleme listesi (stack trace) içindedir.
  2. İstisnanın oluştuğu metotta, onu saran bir try ve uyumlu bir catch aranır.
  3. Bulunamazsa metot o anda sona erer (varsa finally çalışır) ve istisna çağıran metoda geçer. Arama, çağrı yığınında aşağıya doğru sürer.
  4. Uygun bir catch bulunursa o çalışır; program catch'ten sonra devam eder.
  5. main de yakalamazsa JVM'in varsayılan işleyicisi izleme listesini yazdırır ve programı (o iş parçacığını) sonlandırır.
Bu arama sürecine yığın çözülmesi (stack unwinding) denir. Yakalanan istisna nesnesi catch bloğu bitince artık kullanılmaz ve çöp toplayıcı (garbage collector) tarafından temizlenir.

Çalışma Zamanı İstisnaları

RuntimeException Sınıfları

RuntimeException ve alt sınıfları, programcı hatası veya mantık hatası sonucu oluşan istisnaları temsil eder. Derleme zamanında denetlenmez, ele alınmaları zorunlu değildir; ama programcının bu durumları bilinçli olarak önlemesi ya da ele alması gerekir.

SınıfNe zaman oluşur?Örnek
NullPointerExceptionnull bir referansın üyesi kullanılıncaString s = null; s.length();
ArrayIndexOutOfBoundsExceptionDizi sınırları dışında indeksint[] d = new int[3]; d[5] = 1;
ArithmeticExceptionTamsayı sıfıra bölme, kesin aritmetikte taşma10 / 0
IllegalArgumentExceptionMetoda geçersiz argüman verilincenew ArrayList<>(-1)
NumberFormatExceptionMetin geçerli bir sayı değilken dönüştürmeInteger.parseInt("abc")
ClassCastExceptionNesne, dönüştürülmek istenen türde değilken(Integer) nesne

Çalışma Zamanı İstisnaları

NullPointerException

  • null bir referans üzerinden metot çağırmak, alana erişmek veya length almak bu istisnaya yol açar.
  • En sık hata kaynaklarındandır. Önlemek için:
    • if (str != null) ile açık denetim
    • Objects.requireNonNull(x, mesaj): null ise hemen, anlamlı mesajla NPE fırlatır
    • Objects.requireNonNullElse(x, varsayilan) (Java 9+): null ise varsayılan değeri döndürür
    • Optional sınıfı (Java 8+): “değer olmayabilir” durumunu açıkça temsil eder
    • Kütüphaneler: Apache Commons Lang StringUtils, null-güvenli metin işlemleri sunar
String str = null;
int length = str.length();
Çıktı (Java 14+ açıklayıcı mesaj)
Exception in thread "main" java.lang.NullPointerException:
  Cannot invoke "String.length()" because "str" is null
Java 14+ mesajı hangi referansın null olduğunu söyler. Değişken adı hata ayıklama bilgisiyle derlenince (javac -g, IDE'ler) görünür; yoksa "<local1>".

Çalışma Zamanı İstisnaları

null ile Güvenli Çalışmak

1String str = null;
2int length = str.length();
3Objects.requireNonNull(str, "Str null olamaz");
4Optional<String> optionalStr = Optional.ofNullable(str);
5length = optionalStr.map(String::length).orElse(0);
6String defaultValue = Objects.requireNonNullElse(str, "0");
7if (str != null) {
8  System.out.println(str.length());
9}
10System.out.println("Ali".equals(str));
SatırSonuç (her satır tek başına denendiğinde)
2NullPointerException: Cannot invoke "String.length()" because "str" is null
3NullPointerException: Str null olamaz
5length = 0 (değer yok → orElse(0))
6defaultValue = "0"
7–9Koşul yanlış; hiçbir şey yazılmaz, istisna yok
10false: sabit metin önde, null argüman sorun değil

"Ali".equals(str) güvenlidir; str.equals("Ali") ise str null olduğunda NPE fırlatır. requireNonNull, hatayı kaynağında ve anlaşılır bir mesajla yakalamak için metot başlarında kullanılır.

Çalışma Zamanı İstisnaları

ArrayIndexOutOfBoundsException

  • Dizinin sınırları dışındaki bir indekse erişme durumudur: geçerli indeksler 0 … length − 1; negatif indeks de geçersizdir.
  • IndexOutOfBoundsException ailesinin bir üyesidir. Sınır aşımında aynı aileden farklı sınıflar fırlatılabilir:
    • dizi (int[]), Vector, Arrays.asList(...) listesi → ArrayIndexOutOfBoundsException
    • ArrayList.get → IndexOutOfBoundsException (üst sınıf)
    • String.charAt → StringIndexOutOfBoundsException
  • Hepsini birden yakalamak için: catch (IndexOutOfBoundsException e).

Önleme: döngü sınırını length ile yazın

int[] numbers = {1, 2, 3};
for (int i = 0; i < numbers.length; i++) {
  System.out.print(numbers[i] + " ");
}
Çıktı
1 2 3
En sık neden: i <= dizi.length yazmak. Son tur dizi[length]'e erişir ve istisna oluşur.

Çalışma Zamanı İstisnaları

Sınır Aşımı: Hangi Satır Hangi İstisna?

1int[] numbers = {1, 2, 3};
2int value = numbers[5];
3ArrayList<String> list = new ArrayList<>();
4String svalue = list.get(5);
5Vector<Integer> vector = new Vector<>();
6value = vector.get(10);
7String[] names = {"Alice", "Bob", "Charlie"};
8svalue = Arrays.asList(names).get(5);
9String str = "Hello";
10char ch = str.charAt(10);
SatırFırlatılan istisna ve mesajı
2ArrayIndexOutOfBoundsException
Index 5 out of bounds for length 3
4IndexOutOfBoundsException
Index 5 out of bounds for length 0
6ArrayIndexOutOfBoundsException
Array index out of range: 10
8ArrayIndexOutOfBoundsException
Index 5 out of bounds for length 3
10StringIndexOutOfBoundsException
Index 10 out of bounds for length 5

Her satır tek başına denendiğinde. Boş bir ArrayList'in kapasitesi olsa bile boyutu 0'dır; get boyuta göre denetler.

Çalışma Zamanı İstisnaları

ArithmeticException

  • Matematiksel işlemler sırasında oluşan bir hatayı temsil eder; en bilinen örneği tamsayıyı sıfıra bölmek (/ ve %).
  • Math sınıfının “kesin” (exact) metotları taşmada fırlatır: addExact, multiplyExact, toIntExact…
  • BigDecimal yüksek hassasiyetli aritmetik sağlar; sıfıra bölmede veya sonucu tam gösterilemeyen bölmede (1/3) fırlatır.
  • Dikkat: double işlemleri istisna fırlatmaz: 10.0 / 0 → Infinity, Math.sqrt(-1) → NaN.
  • Random.nextInt(0) ise ArithmeticException değil, IllegalArgumentException fırlatır: sınır pozitif olmalıdır.
Sessiz taşma: sıradan int toplaması taşınca istisna oluşmaz, değer başa sarar:
Integer.MAX_VALUE + 1 → -2147483648.
Taşmanın fark edilmesi gerekiyorsa Math.addExact kullanın.

Çalışma Zamanı İstisnaları

Aritmetik Hatalar: Satır Satır

1int result = 10 / 0;
2double dresult = Math.sqrt(-1);
3System.out.println(dresult);
4System.out.println(10.0 / 0);
5int t = Math.addExact(Integer.MAX_VALUE, 1);
6Random random = new Random();
7int randomNumber = random.nextInt(0);
8BigDecimal num1 = new BigDecimal("10");
9BigDecimal num2 = BigDecimal.ZERO;
10BigDecimal bresult = num1.divide(num2);
SatırSonuç
1ArithmeticException: / by zero
3NaN yazar, istisna yok
4Infinity yazar, istisna yok
5ArithmeticException: integer overflow
7IllegalArgumentException: bound must be positive
10ArithmeticException: Division by zero

Her satır tek başına denendiğinde. Kayan noktalı sayılarda sıfıra bölme IEEE 754 kurallarına göre özel değerler (Infinity, NaN) üretir; bu yüzden double sonuçlarını ayrıca denetlemek gerekir (Double.isNaN).

Çalışma Zamanı İstisnaları

IllegalArgumentException

  • Bir metodun geçersiz bir argüman aldığını belirtir. Kontrol edilmeyen bir istisnadır.
  • Argümanları denetleyip fırlatmak, hatayı kaynağında durdurur.
  • Kütüphane örnekleri:
    • Arrays.copyOfRange(d, 5, 2): başlangıç > bitiş
    • new ArrayList<>(-1): negatif kapasite
    • Thread'in setPriority(11): öncelik 1–10 arası olmalı
    • new File(uri): adres file: şeklinde değilse
public void yasAyarla(int age) {
  if (age < 0) {
    throw new IllegalArgumentException("Yaş negatif olamaz");
  }
  this.age = age;
}
public void adAyarla(String name) {
  if (name.length() < 3) {
    throw new IllegalArgumentException("3 karakter olmalı");
  }
  this.name = name;
}
Her geçersiz durum bu istisna değildir: new FileReader("invalid/file/path") → FileNotFoundException; new Thread(null) hiç fırlatmaz. Alt sınıfı: NumberFormatException.

Çalışma Zamanı İstisnaları

Geçersiz Argüman: Satır Satır

1yasAyarla(-5);
2adAyarla("Al");
3int[] numbers = {1, 2, 3};
4Arrays.copyOfRange(numbers, 5, 2);
5List<Integer> liste = new ArrayList<>(-1);
6File file = new File(URI.create("http://ornek.com/a.txt"));
7Thread thread = new Thread(gorev);
8thread.setPriority(11);
SatırFırlatılan istisna (her satır tek başına)
1IllegalArgumentException: Yaş negatif olamaz
2IllegalArgumentException: 3 karakter olmalı
4IllegalArgumentException: 5 > 2
5IllegalArgumentException: Illegal Capacity: -1
6IllegalArgumentException: URI scheme is not "file"
8IllegalArgumentException (mesajsız)

İyi bir mesaj, geçersiz değeri ve beklenen aralığı söyler: "Yaş negatif olamaz: " + age. Mesajsız istisna (8. satır) hata ayıklamayı zorlaştırır.

Çalışma Zamanı İstisnaları

NumberFormatException

  • Bir metin sayıya dönüştürülürken metin geçerli bir sayıyı temsil etmiyorsa oluşur.
  • Integer.parseInt, Double.parseDouble, Float.parseFloat, Short.parseShort, Long.parseLong, Byte.parseByte ve valueOf metotları fırlatabilir.
  • Değer türün aralığı dışındaysa da oluşur: Byte.parseByte("300").
  • IllegalArgumentException'ın alt sınıfıdır.
  • Kullanıcı girdisi her zaman bu riski taşır: ya önceden denetleyin ya da yakalayın.
String strNumber = "abc";
int number = Integer.parseInt(strNumber);
strNumber = "123abc";
number = Integer.parseInt(strNumber);
String strDouble = "12.34abc";
double doubleValue = Double.parseDouble(strDouble);
String strShort = "45xyz";
short shortValue = Short.parseShort(strShort);
ÇağrıNumberFormatException mesajı
Integer.parseInt("abc")For input string: "abc"
Integer.parseInt("123abc")For input string: "123abc"
Double.parseDouble("12.34abc")For input string: "12.34abc"
Short.parseShort("45xyz")For input string: "45xyz"

Çalışma Zamanı İstisnaları

Güvenli Sayı Dönüştürme

static int guvenliOku(String metin, int varsayilan) {
  try {
    return Integer.parseInt(metin.trim());
  } catch (NumberFormatException e) {
    return varsayilan;
  }
}
// main içinde
System.out.println(guvenliOku(" 42 ", 0));
System.out.println(guvenliOku("kırk", 0));
System.out.println(guvenliOku("10.5", -1));
Çıktı
42
0
-1
  • Dönüştürme bir yardımcı metotta tek bir yerde denetlenir; geçersiz girdi için varsayılan değer döner.
  • trim(), baştaki ve sondaki boşlukları siler: parseInt(" 42 ") tek başına istisna fırlatırdı.
  • "10.5" bir int değildir; ondalık sayı için Double.parseDouble kullanılır.
  • Varsayılan değer, geçerli bir sonuçla karışmayacak biçimde seçilmelidir; karışabiliyorsa istisnayı çağırana iletmek daha doğrudur.

Çalışma Zamanı İstisnaları

ClassCastException

  • Bir nesne, dönüştürülmek istendiği türden değilken tür dönüşümü (cast) yapılınca oluşur.
  • Değişkenin türü değil, nesnenin gerçek türü belirleyicidir: Object obj = "Merhaba" bir String nesnesidir.
  • Ham (raw) türlü koleksiyonlar (ArrayList, Map, Set) her türü kabul eder; yanlış türde eleman alınırken dönüşüm başarısız olur. Sıralı koleksiyonlar (TreeSet, TreeMap) karşılaştırılamayan türde eleman eklenirken de fırlatır.
  • Önleme: generics (ArrayList<String>) yanlış türü derleme zamanında yakalar; dönüşümden önce instanceof ile denetleyin.
1Object obj = "Merhaba";
2Integer number = (Integer) obj;
3ArrayList list = new ArrayList();
4list.add("Merhaba");
5number = (Integer) list.get(0);
6Map map = new HashMap();
7map.put("anahtar", "Değer");
8Integer value = (Integer) map.get("anahtar");
9Set set = new HashSet();
10set.add("Merhaba");
11value = (Integer) set.iterator().next();
12Object[] objArray = new String[5];
13Integer[] intArray = (Integer[]) objArray;

2, 5, 8, 11 ve 13. satırların her biri ClassCastException fırlatır, örneğin:

class java.lang.String cannot be cast to class
java.lang.Integer

Çalışma Zamanı İstisnaları

Dönüşümden Önce instanceof

Klasik biçim

Object obj = "Merhaba";
if (obj instanceof Integer) {
  Integer sayi = (Integer) obj;
  System.out.println("Sayı: " + sayi);
} else {
  System.out.println("obj bir Integer değil");
}
Çıktı
obj bir Integer değil

Desen eşleme (Java 16+)

if (obj instanceof Integer sayi) {
  System.out.println("Sayı: " + sayi);
}

Generics ile derleme zamanında

ArrayList<String> liste = new ArrayList<>();
liste.add("Merhaba");
Integer n = (Integer) liste.get(0);
error: incompatible types: String cannot be
  converted to Integer
Çalışma zamanı istisnası yerine derleme hatası: hata daha erken, programı çalıştırmadan bulunur. Ham türlerden kaçının.

Kontrol Edilen Sınıflar

Kontrollü İstisna Sınıfları

Kodun hatayı ele alması ve uygun biçimde kurtarması gereken, çoğunlukla programın dışındaki koşullardan doğan durumları temsil eder. Derleyici ele alınmalarını şart koşar.

SınıfPaketNe zaman?
FileNotFoundExceptionjava.ioAçılmak istenen dosya yok veya açılamıyor
IOExceptionjava.ioGiriş/çıkış işlemlerinde genel hata (üst sınıf)
SQLExceptionjava.sqlVeritabanı erişiminde hata
ParseExceptionjava.textMetni bir biçime göre ayrıştırırken hata
ClassNotFoundExceptionjava.langAdıyla yüklenmek istenen sınıf bulunamadı
InterruptedExceptionjava.langBekleyen iş parçacığı kesildi (Thread.sleep)
NotSerializableExceptionjava.ioSerileştirilemeyen nesne yazılmak istendi

Kontrol Edilen Sınıflar

FileNotFoundException

try {
  FileReader fileReader = new FileReader("dosya.txt");
} catch (FileNotFoundException e) {
  // Dosya bulunamadı durumuyla ilgili işlemler
  System.out.println(e);
}
Çıktı (dosya yokken, Windows)
java.io.FileNotFoundException: dosya.txt
  (The system cannot find the file specified)
  • Bir dosya açılmak istendiğinde dosya bulunamazsa (ya da bir klasörse, okuma izni yoksa) oluşur.
  • IOException'ın alt sınıfıdır; catch (IOException e) onu da yakalar.
  • Göreli yol ("dosya.txt"), programın çalışma klasörüne göre aranır. IDE'lerde bu genellikle proje klasörüdür: dosya “yanlış klasörde” olabilir.
  • Tipik tepki: kullanıcıya bildirip yeni bir ad istemek veya varsayılan değerlerle devam etmek.

Kontrol Edilen Sınıflar

IOException

try {
  BufferedReader reader =
    new BufferedReader(new FileReader(path));
  String line;
  while ((line = reader.readLine()) != null) {
    System.out.println(line);
  }
  reader.close();
} catch (IOException e) {
  // IOException durumuyla ilgili işlemler
  e.printStackTrace();
}
Çıktı (notlar.txt varken)
birinci satır
ikinci satır
  • Giriş/çıkış işlemlerinde oluşan genel hatayı temsil eder; FileNotFoundException gibi birçok alt sınıfı vardır.
  • Sorun: readLine() istisna fırlatırsa reader.close() hiç çalışmaz; dosya açık kalır (kaynak sızıntısı).

✓ try-with-resources ile

try (BufferedReader okuyucu =
    new BufferedReader(new FileReader(path))) {
  String satir;
  while ((satir = okuyucu.readLine()) != null) {
    System.out.println(satir);
  }
} catch (IOException e) {
  System.out.println(e.getMessage());
}

Kontrol Edilen Sınıflar

SQLException

try {
  Connection connection =
    DriverManager.getConnection("jdbc:mysql://localhost/okul");
  PreparedStatement preparedStatement =
    connection.prepareStatement("SELECT user_id FROM users");
  // Sorguyu çalıştırma ve sonuçları alıp işleme
  ResultSet resultSet = preparedStatement.executeQuery();
  while (resultSet.next()) {
    // Sonuçları işleme
    System.out.println("User ID: " + resultSet.getInt("user_id"));
  }
  // Bağlantıyı kapatma
  connection.close();
} catch (SQLException e) {
  // SQLException durumuyla ilgili işlemler
  System.out.println(e);
}
  • Veritabanı işlemleri sırasında bir hata oluştuğunda fırlatılır: bağlantı kurulamadı, SQL sözdizimi yanlış, tablo yok, sürücü yok…
  • getMessage(), getSQLState() ve getErrorCode() ayrıntı verir.
Çıktı (MySQL sürücüsü yokken)
java.sql.SQLException: No suitable driver
found for jdbc:mysql://localhost/okul

Bağlantı da bir kaynaktır; try-with-resources ile kapatılmalıdır. Veritabanı konusu Bölüm 10'da ele alınır.

Kontrol Edilen Sınıflar

ParseException ve ClassNotFoundException

ParseException (java.text)

Bir metin belirli bir biçime göre ayrıştırılırken uyuşmazlık olursa fırlatılır.

try {
  SimpleDateFormat form =
    new SimpleDateFormat("dd/MM/yy");
  Date date = form.parse("01-01-2022");
} catch (ParseException e) {
  // Ayrıştırma hatasıyla ilgili işlemler
  System.out.println(e);
}
Çıktı
java.text.ParseException: Unparseable date: "01-01-2022"

Biçim / bekliyor, metinde - var.

ClassNotFoundException

Bir sınıf adıyla yüklenmek istenirken (Class.forName) sınıf bulunamazsa fırlatılır.

try {
  Class.forName("java.util.Scanner");
  System.out.println("Scanner yüklendi");
  // Var olmayan bir sınıfı yüklemeye çalışma
  Class.forName("com.example.NonExistentClass");
} catch (ClassNotFoundException e) {
  System.out.println(e);
}
Çıktı
Scanner yüklendi
java.lang.ClassNotFoundException:
  com.example.NonExistentClass

Kontrol Edilen Sınıflar

NotSerializableException

class Nokta {               // Serializable değil
  int x = 3, y = 4;
}
// main içinde
try (ObjectOutputStream outputStream =
    new ObjectOutputStream(new ByteArrayOutputStream())) {
  // Nesneyi ObjectOutputStream ile serileştirmeye çalışma
  Nokta notSerializableObj = new Nokta();
  outputStream.writeObject(notSerializableObj);
} catch (NotSerializableException e) {
  System.out.println(e);
} catch (IOException e) {
  System.out.println("Diğer G/Ç hatası: " + e);
}
Çıktı
java.io.NotSerializableException: Nokta
  • Serileştirme (serialization): bir nesnenin bayt akışına dönüştürülmesi (dosyaya yazmak, ağdan göndermek) ve daha sonra geri dönüştürülmesidir.
  • Serializable arayüzünü uygulayan sınıf serileştirilebilir kabul edilir; uygulamayan sınıfın nesnesi yazılmak istenince bu istisna oluşur.
  • IOException'ın (dolaylı) alt sınıfıdır; bu yüzden catch'i IOException'dan önce yazılır.

✓ Çözüm

class Nokta implements Serializable {
  int x = 3, y = 4;
}

Error Sınıfları

Error Sınıfları

  • Programın normal çalışmasını temelden etkileyen, sistem düzeyindeki sorunları temsil eden kontrol edilmeyen türlerdir.
  • Genellikle uygulama kodunun bir satırından değil, JVM'in ve ortamın durumundan kaynaklanır.
  • JVM tarafından fırlatılır; ele alınması veya bildirilmesi önerilmez. Programın düzgün biçimde sonlanması daha uygun bir yaklaşımdır.
  • Yine de Throwable oldukları için teknik olarak catch edilebilirler (bir sonraki slayt).
HataNe zaman?
OutOfMemoryErrorBellek (heap) tükendi
StackOverflowErrorÇağrı yığını taştı: genellikle sonsuz özyineleme
AssertionErrorassert koşulu yanlışsa (yalnızca -ea açıkken)
NoClassDefFoundErrorDerlemede var olan sınıf çalışırken bulunamadı

Error Sınıfları

Error Örnekleri

static void sonsuz() {
  sonsuz();          // durma koşulu yok
}
public static void main(String[] args) {
  try {
    sonsuz();
  } catch (StackOverflowError e) {
    System.out.println("SOE -> " + e);
  }
  try {
    long[] dizi = new long[Integer.MAX_VALUE];
  } catch (OutOfMemoryError e) {
    System.out.println("OOM -> " + e);
  }
  int yas = -5;
  assert yas >= 0 : "Yaş negatif: " + yas;
  System.out.println("assert geçti");
}
java Ornek
SOE -> java.lang.StackOverflowError
OOM -> java.lang.OutOfMemoryError: Requested array size exceeds VM limit
assert geçti
java -ea Ornek
SOE -> java.lang.StackOverflowError
OOM -> java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Exception in thread "main" java.lang.AssertionError: Yaş negatif: -5
  • Özyinelemede taban durum unutulursa her çağrı yeni bir çerçeve ekler; yığın dolar.
  • assert varsayılan olarak kapalıdır; -ea ile açılır. Geliştirirken varsayımları sınamak içindir. (Burada yakalamak yalnızca gösterim içindir.)

Özel İstisnalar

Özel İstisna Sınıfları

public class OzelHata extends Exception {
  // Constructor
  public OzelHata(String message) {
    super(message);
  }
}
Üst sınıfSonuç
extends ExceptionKontrol edilen: çağıran ele almak zorunda; kurtarılabilir iş kuralı ihlalleri
extends RuntimeExceptionKontrol edilmeyen: hatalı kullanım, programcı hatası
  • Geliştirici, kendi programında ortaya çıkabilecek beklenmeyen durumları yönetmek için özel istisna sınıfları oluşturabilir.
  • Throwable'ı genişleten her sınıfın nesnesi fırlatılabilir. Ancak genellikle Exception veya RuntimeException genişletilir; Error ve Throwable doğrudan genişletilmez.
  • Yapıcı, mesajı super(message) ile üst sınıfa iletir; böylece getMessage() çalışır.
  • Ad …Hata / …Exception ile bitirilir; durumu anlatmalıdır.
  • Ek alanlar (eksik tutar, hatalı değer) eklenebilir: istisna sıradan bir sınıftır.

Özel İstisnalar

Özel İstisnayı Fırlatmak ve Yakalamak

public class OzelHataTest {
  public static void main(String[] args) {
    try {
      fonksiyon();
    } catch (OzelHata e) {
      System.out.println("Yakalandı: " + e.getMessage());
    }
  }
  public static void fonksiyon() throws OzelHata {
    if (true) {
      throw new OzelHata("Özel hata oluştu.");
    }
  }
}
Çıktı
Yakalandı: Özel hata oluştu.
  • OzelHata, Exception'dan türediği için kontrol edilen bir istisnadır: fonksiyon() imzasında throws OzelHata zorunludur.
  • main, çağrıyı try içine alarak “ele al” seçeneğini kullanır.
  • if (true) burada yalnızca gösterim içindir: koşulsuz throw'dan sonra gelen bir kod “unreachable statement” hatası verirdi.
  • Gerçek programlarda koşul bir iş kuralını denetler: bakiye yeterli mi, not 0–100 arasında mı, kullanıcı adı boş mu…

Özel İstisnalar · Kodu adım adım çalıştır

Özel İstisna: Banka Hesabı

Yığın: mainHeaphesapHesapbakiye = 100.0

Hesap nesnesi heap'te oluşur; hesap onu gösterir.

Yığın: mainHeaphesapHesapbakiye = 100.0

paraCek(30): 30 > 100 mü? Hayır; istisna yok.

Yığın: mainHeaphesapHesapbakiye = 70.0

Bakiye 70.0 olur ve yazdırılır.

Yığın: mainHeaphesapHesapbakiye = 70.0

paraCek(90): 90 > 70 mi? Evet.

Yığın: mainHeaphesapHesapbakiye = 70.0YetersizBakiyeHatasimesaj: "Bakiye yetersiz"eksik = 20.0

Heap'te bir istisna nesnesi oluşur (mesaj ve eksik = 20.0) ve fırlatılır. Bakiye değişmez.

Yığın: mainHeaphesapHesapbakiye = 70.0YetersizBakiyeHatasimesaj: "Bakiye yetersiz"eksik = 20.0e

paraCek'in çerçevesi atılır; paraCek(10) atlanır. catch eşleşir: e aynı nesneyi gösterir.

Yığın: mainHeaphesapHesapbakiye = 70.0YetersizBakiyeHatasimesaj: "Bakiye yetersiz"eksik = 20.0e

İstisna nesnesinin bilgileri kullanılır. İstisna da sıradan bir nesnedir.

class Hesap {
  private double bakiye;
  Hesap(double bakiye) { this.bakiye = bakiye; }
  public void paraCek(double miktar)
      throws YetersizBakiyeHatasi {
    if (miktar > bakiye) {
      throw new YetersizBakiyeHatasi(
        "Bakiye yetersiz", miktar - bakiye);
    }
    bakiye -= miktar;
    System.out.println("Kalan: " + bakiye);
  }
}
// main içinde
Hesap hesap = new Hesap(100);
try {
  hesap.paraCek(30);
  hesap.paraCek(90);
  hesap.paraCek(10);
} catch (YetersizBakiyeHatasi e) {
  System.out.println(e.getMessage()
    + ", eksik: " + e.getEksik());
}

Özel İstisnalar

Bilgi Taşıyan Özel İstisna

class YetersizBakiyeHatasi extends Exception {
  private double eksik;

  public YetersizBakiyeHatasi(String mesaj, double eksik) {
    super(mesaj);          // mesaj Throwable'da saklanır
    this.eksik = eksik;
  }

  public double getEksik() {
    return eksik;
  }
}
  • Önceki izlemede kullanılan sınıf: mesaja ek olarak eksik tutarı da taşır.
  • Yakalayan kod bu bilgiyle anlamlı bir tepki verebilir: “20 TL eksik; yine de denemek ister misiniz?”
  • -1 gibi bir dönüş kodu bu kadar bilgi taşıyamazdı.
  • Kontrol edilen tür seçildi: yetersiz bakiye öngörülebilir bir durumdur ve çağıran kod bununla başa çıkmalıdır.

İzleme Listesi

İzleme Listesi (Stack Trace)

  • Program çalışırken hangi metot çağrılarının gerçekleştiğini ve istisnanın nerede oluştuğunu gösteren rapordur.
  • İstisnanın türünü ve mesajını; her çağrı için sınıf ve metot adını, dosya adını ve satır numarasını içerir.
  • Yakalanmayan bir istisnada JVM tarafından konsola (System.err) yazdırılır; e.printStackTrace() ile istenildiğinde de yazdırılabilir.
  • Programcının hatayı anlamasına ve sorunu çözmesine yardım eden en önemli ipucudur.
Exception in thread "main" java.lang.NullPointerException
    at com.example.MyClass.myMethod(MyClass.java:10)
    at com.example.MyClass.main(MyClass.java:6)

Okuma: main (6. satır) myMethod'u çağırdı; istisna myMethod'un 10. satırında oluştu. com.example paket, MyClass sınıf adıdır.

İzleme Listesi

İzleme Listesini Okumak

1public class IzlemeOrnegi {
2  static int uzunluk(String metin) {
3    return metin.length();
4  }
5  static void yazdir(String ad) {
6    System.out.println(ad + ": " + uzunluk(ad));
7  }
8  public static void main(String[] args) {
9    yazdir("Ali");
10    yazdir(null);
11    System.out.println("Bitti");
12  }
13}
  1. İlk satır: tür ve mesaj: metin null.
  2. İlk at: istisnanın doğduğu yer (3. satır).
  3. Aşağı doğru çağrı zinciri: main (10) → yazdir (6) → uzunluk (3).
  4. Kendi kodunuzdaki satırlara bakın; asıl neden çoğu zaman aşağıdadır: null'ı 10. satır gönderdi.
Çıktı
Ali: 3
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "metin" is null
    at IzlemeOrnegi.uzunluk(IzlemeOrnegi.java:3)
    at IzlemeOrnegi.yazdir(IzlemeOrnegi.java:6)
    at IzlemeOrnegi.main(IzlemeOrnegi.java:10)

İzleme Listesi

İstisna Yönetiminde İyi Uygulamalar

Özel türü yakalayın

Mümkünse catch (Exception e) yerine beklenen türü yakalayın; her türe uygun tepki verin.

İstisnayı yutmayın

Boş catch { } hatayı gizler. En azından kaydedin (log) veya kullanıcıya bildirin.

Kaynakları kapatın

Dosya, bağlantı gibi kaynaklar için try-with-resources veya finally kullanın.

Önlenebilecekleri önleyin

null, sınır ve sıfır denetimi yapın; RuntimeException yakalamak yerine kodu düzeltin.

Akış denetimi için kullanmayın

Döngüden çıkmak gibi olağan işler için istisna fırlatmayın; istisnalar istisnai durumlar içindir.

Anlamlı mesaj verin

Mesaj hatalı değeri ve beklentiyi söylesin: "Not 0-100 arası olmalı: 120".

Doğru yerde ele alın

Çözebileceğiniz yerde yakalayın; çözemiyorsanız throws ile iletin.

Kayıt tutun

İstisnaları bir dosyaya kaydetmek (logging), sonradan hatanın izini sürmeyi kolaylaştırır.

İzleme Listesi

final, finally ve finalize

Ne?Görevi
finalAnahtar kelimeDeğişken: yeniden atanamaz · metot: geçersiz kılınamaz · sınıf: alt sınıfı olamaz
finallyAnahtar kelime (blok)try'dan sonra, istisna olsun olmasın her durumda çalışan temizlik bloğu
finalize()Object sınıfının metoduÇöp toplayıcı nesneyi silmeden önce çağırabilirdi. Ne zaman çağrılacağı belirsizdir; Java 9'dan beri kullanımdan kaldırılmış (deprecated) durumdadır.
Adları benzer, işleri tamamen farklıdır. Kaynak temizliği için finalize() değil, try-with-resources veya finally kullanılır.

Özet

Özet

KavramÖzü
İstisnaÇalışma zamanında normal akışı bozan durum; türü, mesajı ve yeri olan bir nesne
try / catchRiskli kod try'da; eşleşen ilk catch çalışır, try'ın kalanı atlanır
catch sırasıAlt sınıf önce, üst sınıf sonra; tersi derleme hatası. A | B (Java 7+)
finallyHer durumda çalışır, return'den bile önce; temizlik için
try-with-resourcestry (Kaynak k = …): AutoCloseable kaynak otomatik kapanır
HiyerarşiThrowable → Error | Exception → … RuntimeException
Kontrol edilenException (Runtime hariç): ele al veya throws ile bildir
Kontrol edilmeyenRuntimeException, Error: zorunluluk yok; önle
throw / throwsFırlat (gövdede, nesne) / bildir (imzada, türler)
YayılımYakalanmayan istisna çağıran metoda geçer; main de yakalamazsa program sonlanır
Özel istisnaclass X extends Exception + super(mesaj)
İzleme listesiTür + mesaj, sonra çağrı zinciri: ilk at satırı istisnanın doğduğu yer

Özet

Sık Yapılan Hatalar

Kontrol edilen istisnayı unutmak

new FileReader(ad), try/throws yok: unreported exception FileNotFoundException; must be caught or declared to be thrown.

Genel catch'i öne yazmak

catch (Exception e), sonra catch (ArithmeticException e): exception ArithmeticException has already been caught.

Fırlatılmayanı yakalamak

Dosya işlemi olmayan try'a catch (FileNotFoundException e): exception FileNotFoundException is never thrown in body of corresponding try statement.

Yalnız try yazmak

catch veya finally olmayan try: 'try' without 'catch', 'finally' or resource declarations.

throw'dan sonra kod yazmak

Aynı blokta throw'un ardından gelen satır: unreachable statement.

try içindeki değişkeni dışarıda kullanmak

try içinde tanımlanan sonuc sonra yazdırılırsa: cannot find symbol. Try'dan önce tanımlayın.

İstisnayı yutmak

catch (Exception e) { } derlenir ama hata iz bırakmadan kaybolur.

Metin fırlatmak

throw "hata"; → incompatible types: String cannot be converted to Throwable.

Özet

Örnek Problemler (1)

Problem 1: Çıktı nedir?

static int f() {
  try {
    System.out.print("A");
    int x = 5 / 0;
    System.out.print("B");
    return 1;
  } catch (ArithmeticException e) {
    System.out.print("C");
    return 2;
  } finally {
    System.out.print("D");
  }
}
// main içinde
System.out.println(" " + f());

Problem 2: Çıktı nedir?

try {
  String s = "12a";
  int n = Integer.parseInt(s);
  System.out.println("Sayı: " + n);
} catch (IllegalArgumentException e) {
  System.out.println("IAE");
} catch (Exception e) {
  System.out.println("Exception");
}

Problem 3

Problem 2'de iki catch bloğunun yeri değiştirilirse ne olur?

Cevapları göster
  1. ACD 2: “A”; bölmede istisna (B ve return 1 atlanır); catch “C” yazar, 2'yi hazırlar; finally “D” yazar; 2 döner.
  2. IAE: NumberFormatException, IllegalArgumentException'ın alt sınıfıdır.
  3. Derleme hatası: exception IllegalArgumentException has already been caught.

Özet

Örnek Problemler (2)

Problem 4: Çıktı nedir?

static void a() {
  System.out.print("a1 ");
  b();
  System.out.print("a2 ");
}
static void b() {
  System.out.print("b1 ");
  throw new IllegalStateException("!");
}
// main içinde
try {
  a();
  System.out.print("m ");
} catch (IllegalStateException e) {
  System.out.print("yakalandı" + e.getMessage());
} finally {
  System.out.println(" son");
}

İstisna b()'de doğuyor; b() ve a()'da try yok. Hangi print'ler çalışır, hangileri atlanır? finally ne zaman çalışır?

Cevabı göster

a1 b1 yakalandı! son

İstisna b → a → main yolunu izler: “a2” ve “m” atlanır. main'deki catch yakalar, ardından finally “ son” yazar ve satırı bitirir.

Özet

Örnek Problemler (3)

Problem 5: toplam kaçtır?

int[] d = {4, 0, 2};
int toplam = 0;
for (int i = 0; i <= d.length; i++) {
  try {
    toplam += 12 / d[i];
  } catch (ArithmeticException e) {
    toplam += 100;
  } catch (ArrayIndexOutOfBoundsException e) {
    toplam += 1000;
  }
}
System.out.println(toplam);

Problem 6: Çıktı nedir?

try {
  throw new RuntimeException("X");
} finally {
  System.out.println("F");
}
Cevapları göster
  1. 1109: 12/4 = 3, 12/0 → +100, 12/2 = 6, d[3] → +1000. Her tur kendi try'ı ile korunduğu için döngü sürer.
  2. Önce F, ardından Exception in thread "main" java.lang.RuntimeException: X: finally çalışır ama istisna yakalanmadığı için program sonlanır.

Özet

Alıştırmalar (1)

  1. Metni yaşa çeviren int yasOku(String metin) yazın: sayı değilse NumberFormatException doğal olarak oluşsun, negatifse IllegalArgumentException fırlatın. "20", "-3", "yirmi" girdileri için iki catch ile mesaj yazdırın.
  2. GecersizNotHatasi adlı kontrol edilen bir istisna ve not 0–100 dışındaysa onu fırlatan notGir(int not) yazın.
  3. 1. alıştırmada catch sırası IllegalArgumentException, sonra NumberFormatException olursa ne olur?
Cevaplar / ipuçları
  1. int yas = Integer.parseInt(metin); if (yas < 0) throw new IllegalArgumentException("Yaş negatif: " + yas); return yas; · Çıktı: Yaş: 20, Yaş negatif: -3, Sayı değil: yirmi. NFE catch'i önce yazılmalı.
  2. class GecersizNotHatasi extends Exception { … super(mesaj); } · void notGir(int not) throws GecersizNotHatasi { if (not < 0 || not > 100) throw new GecersizNotHatasi("Not 0-100 arası olmalı: " + not); … } · notGir(120) → Not 0-100 arası olmalı: 120.
  3. Derleme hatası: exception NumberFormatException has already been caught (NFE, IAE'nin alt sınıfı).

Özet

Alıştırmalar (2)

  1. Sınıflandırın (kontrol edilen / edilmeyen): IOException, NumberFormatException, SQLException, NullPointerException, FileNotFoundException, ClassCastException, StackOverflowError.
  2. Bir BufferedReader'ı finally ile kapatan kodu try-with-resources ile yeniden yazın.
  3. double ortalama(int[] notlar) metodu boş dizi için ne yapmalı? 0 mı döndürmeli, istisna mı fırlatmalı? Hangi istisna?
Cevaplar / ipuçları
  1. Kontrol edilen: IOException, SQLException, FileNotFoundException · edilmeyen: NumberFormatException, NullPointerException, ClassCastException, StackOverflowError (Error).
  2. try (BufferedReader r = new BufferedReader(new FileReader(yol))) { … } catch (IOException e) { … }: close() otomatik çağrılır.
  3. 0 geçerli bir ortalamayla karışır (−1 dönüş kodu gibi). Boş dizi geçersiz bir argümandır: throw new IllegalArgumentException("Dizi boş");

Özet

Kaynaklar

  • Oracle, The Java Tutorials: Lesson: Exceptions (Catching and Handling Exceptions; The try-with-resources Statement; Unchecked Exceptions — The Controversy).
  • J. Gosling ve diğ., The Java Language Specification, Java SE 21 Edition, Bölüm 11: Exceptions; 14.20 The try statement.
  • Oracle, Java SE 21 API Documentation: java.lang.Throwable, Exception, RuntimeException, Error.
  • P. Deitel ve H. Deitel, Java: How to Program, 11. baskı, Pearson (Bölüm 11: Exception Handling: A Deeper Look).
  • K. Sierra, B. Bates ve T. Gee, Head First Java, 3. baskı, O'Reilly (Risky Behavior: exception handling).
  • C. S. Horstmann, Core Java, Volume I: Fundamentals, 12. baskı, Pearson (Bölüm 7: Exceptions, Assertions, and Logging).
  • J. Bloch, Effective Java, 3. baskı, Addison-Wesley (Bölüm 10: Exceptions, Madde 69–77).

Son

Bölüm 6: Hata Ayıklama ve İstisnalar
Sonraki bölüm: Bölüm 7: Giriş Çıkış
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.