Bölüm 6: Hata Ayıklama ve İstisnalar
Çoktan Seçmeli · İstisna Kavramı
Soru 1: Hata Türü
Ortalama hesaplayan bir programda toplam yanlışlıkla 3 yerine 2'ye bölünüyor. Program derleniyor, çalışıyor ve bir sayı yazıyor; ama sayı yanlış. Bu hangi tür hatadır?
C: Kod dil kurallarına uyduğu için derlenir ve hiçbir işlem geçersiz olmadığı için istisna da oluşmaz. Mantık hataları ancak beklenen sonuçla karşılaştırarak, yani testlerle bulunur. İstisna mekanizması yalnızca ortadaki türü (çalışma zamanı hatalarını) ele alır.
Çıktı Sorusu · İstisna Kavramı
Soru 2: Yakalanmayan İstisna
Program ne yazdırır? "B" neden yazılmaz? İzleme listesindeki satır numaraları neyi gösterir?
public class Bolme { static int f(int[] d) { return 10 / (d.length - 2); } public static void main(String[] args) { System.out.println("A"); System.out.println(f(new int[3])); System.out.println(f(new int[2])); System.out.println("B"); } }
Cevabı göster
A
10
Exception in thread "main"
java.lang.ArithmeticException: / by zero
at Bolme.f(Bolme.java:3)
at Bolme.main(Bolme.java:8)(İstisna satırı ekranda tek satırdır; burada bölündü.)
İlk çağrıda 10 / 1 = 10. İkincide payda 0: tam sayı bölmesi ArithmeticException fırlatır. f de main de yakalamadığı için program sonlanır; 9. satır hiç çalışmaz.
İlk at istisnanın doğduğu yer (f, 3. satır), alttaki onu çağıran satırdır (main, 8).
Adım Adım Çalıştırma · try ve catch
Soru 3: Hangi catch Çalışır?
dene sırasıyla "5", "x", "1", "-2" ve "0" ile çağrılıyor. Her çağrıda hangi blok çalışır, ne yazdırılır?
d = new int[5], d[4] = 100 / 4 = 25. İstisna olmadığı için hiçbir catch çalışmaz.
NumberFormatException (3. satır) ilk catch ile eşleşmez; bir RuntimeException olduğu için ikincisi yakalar.
n − 1 = 0: bölmede ArithmeticException. İlk catch eşleşir; ikinci denenmez.
Negatif boyutla dizi oluşturulamaz: NegativeArraySizeException, bir RuntimeException.
İndis (−1) ve sağ taraf (−100) hesaplanır; atamada indis denetlenince ArrayIndexOutOfBoundsException.
static void dene(String s) { try { int n = Integer.parseInt(s); int[] d = new int[n]; d[n - 1] = 100 / (n - 1); System.out.println("tamam " + d[n - 1]); } catch (ArithmeticException e) { System.out.println("A"); } catch (RuntimeException e) { System.out.println("R " + e.getClass().getSimpleName()); } }
Çoktan Seçmeli · try ve catch
Soru 4: catch Sırası
Bu kod için hangisi doğrudur?
try { int s = 10 / 0; } catch (Exception e) { System.out.println("Genel"); } catch (ArithmeticException e) { System.out.println("Aritmetik"); }
A: catch blokları yukarıdan aşağıya denenir; Exception bloğu her ArithmeticException'ı zaten yakalar, ikinci blok asla çalışamaz. Derleyici erişilemeyen catch'e izin vermez. Kural: alt sınıf önce, üst sınıf sonra.
Adım Adım Çalıştırma · finally
Soru 5: finally ve return
Program ne yazdırır? finally, return'den önce mi sonra mı çalışır?
f(5): try başlar, "T5 " yazılır.
return 10 / x: dönüş değeri 2 hesaplanır ve bekletilir; metot henüz bitmez.
Metottan çıkmadan önce finally çalışır: "F ".
Bekleyen 2 döner; println yazar ve satırı bitirir.
f(0): "T0 ".
throw: try'ın kalanı (return 10 / x) atlanır; 0'a bölme hiç denenmez.
Eşleşen catch "C " yazar; return -1 değeri bekletir.
Yine finally: "F ".
−1 döner. finally her iki yolda da, dönüşten hemen önce çalıştı.
static int f(int x) { try { System.out.print("T" + x + " "); if (x == 0) { throw new IllegalStateException(); } return 10 / x; } catch (IllegalStateException e) { System.out.print("C "); return -1; } finally { System.out.print("F "); } } // main içinde System.out.println(f(5)); System.out.println(f(0));
Çoktan Seçmeli · finally
Soru 6: finally Değişkeni Değiştirirse
Program ne yazdırır?
static int g() { int s = 1; try { s = 2; return s; } finally { s = 3; System.out.print(s + " "); } } // main içinde System.out.println(g());
B: return s; çalıştığında dönüş değeri (2) hesaplanıp saklanır; sonra finally çalışır. finally s'yi 3 yapar ve "3 " yazar, ama saklanmış dönüş değeri değişmez: main 2 yazar. finally içinde ayrıca return olsaydı o değer dönerdi (önerilmez).
Çıktı Sorusu · finally
Soru 7: İki Kaynaklı try-with-resources
Program ne yazdırır?
class K implements AutoCloseable { String ad; K(String ad) { this.ad = ad; System.out.println(ad + " açıldı"); } public void close() { System.out.println(ad + " kapandı"); } } // main içinde try (K a = new K("A"); K b = new K("B")) { System.out.println("iş"); throw new RuntimeException("hata"); } catch (RuntimeException e) { System.out.println("catch " + e.getMessage()); } finally { System.out.println("finally"); }
Cevabı göster
A açıldı B açıldı iş B kapandı A kapandı catch hata finally
Kaynaklar yazıldıkları sırayla açılır, ters sırayla kapanır: son açılan önce kapanır.
Kapatma, istisna olsa bile ve catch'ten önce yapılır; ardından catch, en son finally çalışır.
Çıktı Sorusu · finally
Soru 8: İç İçe try
Program ne yazdırır?
try { try { Object o = "12"; Integer i = (Integer) o; System.out.println("iç try sonu"); } catch (NumberFormatException e) { System.out.println("iç catch"); } finally { System.out.println("iç finally"); } System.out.println("dış try sonu"); } catch (ClassCastException e) { System.out.println("dış catch"); } finally { System.out.println("dış finally"); } System.out.println("son");
Cevabı göster
iç finally dış catch dış finally son
o bir String nesnesidir; Integer'a dönüşüm ClassCastException fırlatır ("12" sayıya benzese de dönüşüm yapılmaz).
İç catch bu tipi yakalamaz; istisna dışa ilerlerken iç finally çalışır. Dış try'ın kalanı ("dış try sonu") atlanır, dış catch yakalar, dış finally çalışır ve program devam eder.
Çoktan Seçmeli · İstisna Hiyerarşisi
Soru 9: Hangi catch Yakalar?
new FileReader("yok.txt") bir FileNotFoundException fırlatıyor. Aşağıdaki catch tiplerinden hangisi onu yakalar?
D: Bir catch, yazılan tipi ve tüm alt sınıflarını yakalar. FileNotFoundException → IOException → Exception → Throwable zincirindedir. RuntimeException ve SQLException ayrı dallardır; Error Exception ailesinden değildir.
Çoktan Seçmeli · İstisna Türleri
Soru 10: Kontrol Edilen İstisnalar
Hangi gruptaki istisnaların hepsi kontrol edilen (checked) istisnadır?
A: Kontrol edilen istisnalar Exception'dan türeyip RuntimeException'dan türemeyenlerdir; derleyici "yakala ya da bildir" kuralını uygular. NullPointerException, NumberFormatException ve ClassCastException RuntimeException alt sınıflarıdır.
Hata Bulma · İstisna Türleri
Soru 11: Derlenmeyen Okuma Metodu
Derleyici bu metot için hangi hataları verir? İki farklı düzeltme yazın.
static String ilkSatir(String yol) { BufferedReader r = new BufferedReader(new FileReader(yol)); return r.readLine(); }
Cevabı göster
error: unreported exception FileNotFoundException; must be caught or declared to be thrown error: unreported exception IOException; must be caught or declared to be thrown
FileReader yapıcısı ve readLine() kontrol edilen istisna fırlatır. 1) Bildir (çağıran ele alır); dosya da kapanır:
static String ilkSatir(String yol) throws IOException { try (BufferedReader r = new BufferedReader(new FileReader(yol))) { return r.readLine(); } }
2) Ele al: aynı try-with-resources'a catch (IOException e) { return null; } eklenir ve throws kaldırılır. IOException, FileNotFoundException'ı da kapsar.
Adım Adım Çalıştırma · İstisna Fırlatma
Soru 12: İstisnanın Yayılımı
İstisna hangi metotta doğar, hangi satırlar atlanır? Program ne yazdırır?
main → b(1) → c(1): üç çerçeve.
1 > 2 yanlış; c normal biter, çerçevesi kaldırılır.
b ikinci kez c'yi çağırır: c(3).
3 > 2: istisna fırlatılır. c'de try yok: c o anda sona erer, "c bitti" yazılmaz.
b'de catch yok ama finally var: çalışır, sonra istisna yoluna devam eder. "b bitti" atlanır.
main'deki catch eşleşir. "main devam" atlanmıştır.
catch'ten sonra program normal akışına döner.
static void c(int x) { System.out.println("c " + x); if (x > 2) throw new IllegalArgumentException("x=" + x); System.out.println("c bitti"); } static void b(int x) { try { c(x); c(x + 2); System.out.println("b bitti"); } finally { System.out.println("b finally"); } } // main içinde try { b(1); System.out.println("main devam"); } catch (IllegalArgumentException e) { System.out.println("main: " + e.getMessage()); } System.out.println("son");
Çoktan Seçmeli · İstisna Fırlatma
Soru 13: throw ve Bildirim
Bu metot için hangisi doğrudur?
static void f(int x) { if (x < 0) { throw new Exception("negatif"); } }
C: Exception (RuntimeException olmayan) kontrol edilen bir istisnadır: unreported exception Exception; must be caught or declared to be thrown. Çözüm: imzaya throws Exception eklemek ya da IllegalArgumentException gibi kontrol edilmeyen bir tip fırlatmak. throw gövdenin her yerinde kullanılabilir (D).
Çıktı Sorusu · Çalışma Zamanı İstisnaları
Soru 14: Satır Satır İstisnalar
Her satır tek başına çalıştırılıyor. Hangi istisna fırlatılır?
1 Object o = "5"; Integer i = (Integer) o; 2 char c = "abc".charAt(3); 3 int n = Integer.parseInt(" 7"); 4 int m = Math.addExact(Integer.MAX_VALUE, 1); 5 int g = new ArrayList<Integer>().get(0); 6 int[] d = null; d[0] = 1; 7 int[] e = new int[-1];
Cevabı göster
| Satır | İstisna |
|---|---|
| 1 | ClassCastException: nesne bir String |
| 2 | StringIndexOutOfBoundsException: indisler 0 … 2 |
| 3 | NumberFormatException: baştaki boşluk |
| 4 | ArithmeticException: integer overflow |
| 5 | IndexOutOfBoundsException: boyut 0 |
| 6 | NullPointerException |
| 7 | NegativeArraySizeException |
Hepsi RuntimeException alt sınıfıdır: derleyici hiçbirini zorunlu tutmaz. Sıradan + taşmada istisna fırlatmaz; addExact fırlatır.
Çoktan Seçmeli · Çalışma Zamanı İstisnaları
Soru 15: İstisnasız Satır
Aşağıdaki ifadelerden hangisi çalışırken istisna fırlatmaz?
D: Kayan noktalı bölme IEEE 754 kurallarına uyar: 10.0 / 0 Infinity üretir, istisna yoktur. Tam sayı bölmesi ve kalan 0 ile ArithmeticException: / by zero; toIntExact int aralığına sığmayan değerde integer overflow fırlatır.
Çoktan Seçmeli · Kontrol Edilen Sınıflar
Soru 16: Derleyicinin İstediği
main içinde, try-catch ve throws olmadan yazılınca hangisi derlenmez?
B: Thread.sleep kontrol edilen InterruptedException fırlatabileceğini bildirir: unreported exception InterruptedException. Diğerleri en fazla kontrol edilmeyen istisna fırlatır (NumberFormatException, IllegalArgumentException, NullPointerException); derleyici bunları denetlemez.
Çoktan Seçmeli · Error Sınıfları
Soru 17: Sonsuz Özyineleme
Program çalıştırılınca ne olur?
static int f(int n) { return f(n + 1); } public static void main(String[] args) { try { f(0); } catch (Exception e) { System.out.println("yakalandı"); } System.out.println("son"); }
C: Her çağrı yığına yeni bir çerçeve ekler; yığın dolunca JVM StackOverflowError fırlatır. Bu bir Error'dur, Exception ailesinden değildir: catch (Exception e) yakalamaz, program izleme listesiyle sonlanır. Derleyici sonsuz özyinelemeyi denetlemez.
Kod Yazma · Özel İstisnalar
Soru 18: Özel İstisna Sınıfı
Kontrol edilen bir GecersizNotHatasi sınıfı ve int notGir(int not) metodunu yazın: not 0–100 dışındaysa istisna "Not 0-100 arası olmalı: …" mesajıyla fırlatılsın, geçerliyse not dönsün. main içindeki döngü ne yazdırır?
for (int g : new int[]{85, 120, 40}) { try { System.out.println("Kaydedildi: " + notGir(g)); } catch (GecersizNotHatasi e) { System.out.println("Hata: " + e.getMessage()); } }
Cevabı göster
class GecersizNotHatasi extends Exception { GecersizNotHatasi(String m) { super(m); } } static int notGir(int not) throws GecersizNotHatasi { if (not < 0 || not > 100) { throw new GecersizNotHatasi( "Not 0-100 arası olmalı: " + not); } return not; }
Kaydedildi: 85 Hata: Not 0-100 arası olmalı: 120 Kaydedildi: 40
Kontrol edilen tip: throws zorunlu. try döngünün içinde: 120 hatası 40'ı engellemez.
Kod Okuma · İzleme Listesi
Soru 19: İzleme Listesini Okumak
Program ne yazdırır? İzleme listesine göre istisna hangi satırda doğar, null değeri nereden gelir, "bitti" neden yazılmaz?
1 public class Okul { 2 public static void main(String[] args) { 3 int[] a = {70, 80}; 4 int[] b = null; 5 rapor("A", a); 6 rapor("B", b); 7 System.out.println("bitti"); 8 } 9 static void rapor(String ad, int[] d) { 10 System.out.println(ad + ": " + ortalama(d)); 11 } 12 static double ortalama(int[] notlar) { 13 int t = 0; 14 for (int n : notlar) { 15 t += n; 16 } 17 return (double) t / notlar.length; 18 } 19 }
Cevabı göster
A: 75.0
Exception in thread "main"
java.lang.NullPointerException
at Okul.ortalama(Okul.java:14)
at Okul.rapor(Okul.java:10)
at Okul.main(Okul.java:6)- İlk
atsatırı doğduğu yeri gösterir:ortalama, 14. satır. for-each null bir dizinin uzunluğunu okumaya çalışır. - Aşağı doğru okununca zincir:
main(6) →rapor(10) →ortalama(14). null, 4. satırdab'ye atanıp 6. satırda gönderilmiştir: düzeltilecek yer çoğu zaman istisnanın doğduğu yer değil, değeri üreten yerdir. - Kimse yakalamadığı için program sonlandı; 7. satır çalışmadı.
Java 14 ve sonrası mesaja hangi değerin null olduğunu da ekler ("Cannot read the array length …").