Yazan : Şadi Evren ŞEKER

Nesne yönelimli programlama dillerinde istisnai bir durumu, beklenmedik bir olayı algılayıp buna karşı bir kod parçasının çalışmasıdır.

Örneğin hafıyza bir dosya okuyacak olalım. Bu işlemler sırasında:

  • dosyanın disk üzerinden bulunarak açılması
  • dosyanın boyutunun belirlenmesi
  • dosya için hafızda boyutu kadar yer açılması
  • dosyanın bu hafızada açılmış yere yüklenmesi
  • dosyanın kapatılması

işlemlerinin sırasıyla yapılması gerekir. Ancak bu işlemler sırasında beklenmedik bir şekilde dosya diskte bulunmayabilir. Veya hafızada yeterli yer olmaması ihtimali de vardır. Veya hafızaya yükleme sırasında bir hata ile karşılaşılabilir.

İşte yukarıda sayılan bu istisnai ve beklenmedik durumların programlama dilinde algılanması ve bu durum olduğunda hatanın bir şekilde kotarılması (kabz edilmesi, handle) mümkündür.

Klasik fonksiyonel dillerden ileri olarak nesne yönelimli programlama dillerinde bu durumun çözümü olarak try / catch blokları geliştirilmiştir.

Örneğin aşağıdaki örnek kodu ele alalım:

try{
   File f = new File("a.txt");
   InputStreamReader is = new InputStreamReader(new FileInputStream(f));
   char c=(char)is.read();
   while(c!=-1){
      c=(char)is.read();
      System.out.println(c);
   }
}
catch(FileNotFoundException e){
   System.out.println("a.txt dosyası bulunamadı");
}catch(IOException e){
   System.out.println("Dosyadan okurken hata oldu");
}

Yukarıdaki örnek kodda, öncelikle a.txt isminde bir dosya açılmış daha sonra bu dosyayı okumak için JAVA’da bulunan InputStreamReader sınıfından bir nesne tanımlanmış. Ardından dosya sonuna ulaşana kadar (end of file , burada -1) dosyadan karakter karakter okunarak ekrana basılmıştır.

Bu kodda iki adet istisnai durum olabilir. Bunlardan birincisi dosyanın ilk açıldığı sırada FileNotFoundException ikincisi ise dosyadan her okuma sırasında IOException olma olasılığıdır. Bu durumlar için kodun istisnai duruma sebep olabilecek satırları try bloğunun içine alınır. Buradaki satırlarda bir problem çıkması durumunda ise ilgili catch bloğuna gitmesi beklenir.

Yani örneğin a.txt dosyası diskte bulunamazsa ekrana “a.txt dosyası bulunamadı” mesajı basılır.

Kendi istisnamızı yazmak

JAVA dilinde, ayrıca kendi istisnalarımızı da yazabiliriz.

Yukarıdaki deneme isimli fonksiyonda, bir dizinin içerisine kullanıcıdan girilen sayılar yerleştirilmek istenmiş. Diyelim ki dizideki sayıların eksi değerde olmasını istemiyoruz ve eksi değerde girilen sayılar için bir istisna (exception) tanımlayıp bu tip bir sayı girildiğinde istisna fırlatacağız.

Kodda her okunan değerden sonra bir if kontrolü ile, girilen değerin eksi olması halinde “throw new eksiException()” şeklinde fırlatma işlemi gerçekleşmiştir.

Yukarıdaki kodda fırlatılan exception aşağıdaki şekilde kodlanabilir.

Görüldüğü üzere yeni tanımladığımız istisna(exception) bir sınıf olup (class) özellikle Exception sınıfını miras almıştır (inheritance). Bunun sebebi bütün istisnaların tepesinde olan Exception sınıfının her istisna tarafından miras alınması zorunluluğudur. Daha hususi olarak örneğin IOException sınıfı da miras alınabilir. Bu durumda tanımladığımız yeni istisna sınıfımız IOException sınıfının bir alt sınıfı olacak ve bu istisnanın oluşma durumunun giriş çıkış işlemleri ile ilgili olduğu anlaşılacaktır. Unutulmamalıdır ki IOException da bir Exception sınıfıdır ve kendisi Exception sınıfından miras alır. Bu durumda aslında bizim IOException sınıfını miras almamız daha yukarıdaki Exception sınıfını da miras aldığımız anlamına gelmektedir. Kısacası bütün istisna sınıfları doğrudan veya dolaylı olarak Exception sınıfnı miras almak zorundadır.

Yukarıdaki istisna sınıfımızda basit bir dizgi (string) değişkeni tanımlanmış ve iki adet yapıcı metot (constructor method) birbirinin üzerine yüklenmiştir (overloading).

İstisna üretmek ve üretilen istisyanı fırlatmak istediğimiz yerde, bu istisnadan yeni bir nesne (object) üretmemiz yeterli olacaktır. Nitekim bir önceki kodda,

throw new eksiException(“okunan deger eksi”);

şeklinde kodlanan satır, yeni bir eksiException nesnesi üretmiş, üretilen bu nesnenin içerisine parametre olarak bir dizgi vermiş (dolayısıyla ikinci yüzerine yükleme fonksiyonunu çağırmış) ve bu nesneyi fırlatmıştır (throw).

Fırlatılan bu istisna, try bloğunun hemen altındaki yakalama (catch) bloğuna düşmekte ve hata burada telafi edilmektedir. Hatayı telafi etmek için eksi değerleri, -1 ile çarparak artı değere çevirip diziye (array) yerleştiriyoruz. Kodun çıktısı aşağıda verilmiştir:

Kodun çıktısında görüldüğü üzere, sonuç dizisi ekrana basıldığında, kullanıcının eksi değerde girdiği -45, -2 gibi değerler artıya çevirilerek diziye eklenmiştir.

Kodlamayı biraz daha ilerletip fırlatılan istisnayı yakalamamayı deneyelim:

Yukarıdaki yeni kodda, try/catch bloğunu kaldırdık. Bu durumda kodu çalıştırmayı denersek aşağıdaki hatayı alırız:

Görüldüğü üzere, JAVA bizi uyarıyor ve diyor ki t.deneme() fonksiyonun çağırıldığı 15. satırda try/catch bloğu bulunmalı, çünkü fonksiyon buraya bir istisna fırlatıyor ve bu istisna yakalanmamış.

Dikkat edilrise, kodun 18 satırında fonksiyon tanımını yaparken fonksiyona

public void deneme() throws eksiException{

şeklinde bir throws ibaresi ekledik. Bunun anlmaı deneme fonksiyonunun bir öncekinden farklı olarak istisnayı kendisinin çözemediği ancak bu istisnayı daha yukarıda, kendisini çağıran kişye fırlattığıdır. Gerçekten de koddaki 15. satırda t.deneme() şeklinde çağırım, istisnayı yakalamak zorundadır.

Kodumuzda ilgili düzeltmeyi yapıp, t.deneme() çağırımını, try/catch bloklarının arasına yerleştiriyoruz. Kodun yeni çıktısı aşağıdaki şekildedir:

Son kodumuzda, kendi istisnamızı oluşturup bunu fırlatıp daha yukarıdaki bir fonkisyon içerisinde yakaladık. İstisna fırlatılırken içerisine bir mesaj yerleştirildi ve bu mesaj daha yukarıdan çağrılırken okunup ekrana basıldı.

Yorumlar

  1. betül demir

    merhaba hocam,

    try catch konusunda, throw ‘u sadece kendi exception ımızı oluşturduğumuzda mı kullanacağız ?

    bir de diyelim ki fonksiyonun başında yada main in başında throws kullandık.fonksiyonun içinde mutlaka try catch etmeliyiz..kendi excepiton ımız varsa (try/catch kullanmadan) exception ı throw edebiliriz değil mi?

    ((hocam peki sorun olabilecek kısmı try blogu içine yazmadan sadece throw kullanırsak program hata vermez mi? yoksa hata nerde olursa olsun throw tanımladığımız için hatayı yakalayacak mı ?))

    teşekkürler

  2. Şadi Evren ŞEKER Article Author

    try/catch bloğu içerisinde, istediğiniz bir exception’ı throw edebilirsiniz. Bu exceptionın, o alanda tanımlı olması gerekir. Ya JAVA’da tanımlı olan exceptionlardan birisini throw edeceksiniz ya da yeni bir exception kendiniz yazarak throw edeceksiniz.

    fonksiyonun bir şekilde bir exception’ı throws etmesi, bu fonksiyonda throws olarak belirtilen exception’ın bir yerde throw edildiği anlamına gelir.

    throw edilen herşey ya try bloğuna yerleştirilip catch edilmelidir ya da throw edildiği yerden de throws ile daha sonraki çağırımlara throw edilmelidir.

    Yukarıdaki yazıya konuyu anlatıcı bir örnek ekliyorum.

    başarılar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir