Jan 1, 0001  

title: Java Dersleri 19 - İstisnai Durumlar (Exceptions) link: http://orhanbalci.net/tr/?p=933 author: Orhan Balci description: post_id: 933 created: 2010/12/14 14:43:27 created_gmt: 2010/12/14 11:43:27 comment_status: open post_name: java-dersleri-18-istisnai-durumlar-exceptions status: publish post_type: post

Java Dersleri 19 - İstisnai Durumlar (Exceptions)

[caption id=“attachment_940” align=“aligncenter” width=“600” caption=“Java Dersleri 19”]Java Dersleri 19[/caption] Java’nın program akışı esnasında meydana gelebilecek hataları işleme mekanizmasına istisnai durumların işlenmesi denir. Mekanizmnın sentaktik ayrıntılarına geçmeden önce böyle bir aracın ne için ortaya çıktığını ve avantajlarını bilmekte fayda var. İstisnai durumların en önemli avantajı hata işleme kodlarını algoritma kodlarından ayırmaktır. eğer bu mekanizma olmasaydı yaptığımız her işlemden sonra o işlemin doğru olup olmadığını kontrol eden kodlar yazmak zorundaydık. Bu mekanizma sayesinde hata yakalama kodlarımızı algoritma bloğundan ayırabiliriz. İkinci avantaj ise hatayı kolay bir şekilde call-stack hiyerarşisinde üst katmanlara iletmektir. Bu mekanizma olmasaydı yine bu iş için fazladan kod yazmamız gerekecekti. Üçüncü avantaj ise hatayı bir sınıf içinde kapsülleyip hatalar arasında bir hiyerarşi oluşturabilir, hata grupları tanımlanabilir. İstisnai durumların faydalarını gördükten sonra Java kütüphanelerinde tanımlı 3 temel istisnai durum grubunu görelim. Bunlar :

  1. Checked İstisnai Durumlar
  2. Hatalar
  3. Çalışma Zamanı İstisnai Durumları Checked istisnai durumları programımızın yakalaması gereken hata türleridir. Genellikle bu hata türlerinden programımızı bertaraf edip sağlıklı bir şekilde çalışmasına devam ettirebiliriz. İkinci grubumuz olan hatalar ise sistemde meydana gelen anormal olayları simgeler ve uygulamaların çoğunluğu bu hatalardan geri dönemez. Dolayısıyla yakalanmaları zorunlu değildir. Hatalar genellikle virtual machine tarafında alt seviyelerde kullanılırlar. Örneğin tüm Java programcılarının en az bir kere görmüş olduğu java.lang.NoClassDefFoundError hatalar grubunun en klasik örneklerindendir. Son grubumuz olan Çalışma zamanı istisnai durumları ise sistemden değil genellikle kodlama hatalarından kaynaklanan istisnai durumlardır. Buffer overflow hataları, array indeksleme hataları, aritmetik hatalar bu kategoriye girerler. En meşhurları java.lang.ArrayIndexOutOfBoundsException’dır diyebilirim. Bu tür hatalarında yakalanması mecburi değildir. Bu gruplardan bahsettikten sonra istisnai durumun yakalanması veya belirtilmesi zorunluluğu nedir ondan bahsedelim. Yukarıda da değindiğim gibi Checked istisnai durum kategorisine girenlerin yakalanması veya belirtilmesi gereklidir. Yani Checked istisnai durum fırlatması muhtemel kodu içeren metodun ya o durumu kendi içinde yakalaması gerekir yada bir şekilde o metodu çağıranlara kodun istisnai durum üretebileceğini bildirmesi gerekir. Şimdi koyuyla belirttiğimiz kavramlara açıklık getirelim. İstisnai Durumların Yakalanması : Eğer yazdığımız kod parçasında checked exception fırlattığı belirtilen bir metod kullanıyorsak o metodu try/catch bloğuna alarak istisnai durumu yakalayabiliriz. Try/Catch blokları bu tarz hataları yakalamak için kullanılan yapılardır. Örnek bir try/catch bloğu şu şekilde olabilir : [java] public static void dosyaOku(String dosyaAdi) { try { FileReader fr = new FileReader(dosyaAdi); } catch (FileNotFoundException ex) { System.out.println(“FileNotFoundException yakalandı”); } finally { System.out.println(“Eninde sonunda buraya düşer”); } } [/java] Try/Catch bloğunun 3 elemanı vardır. Bunlar hatanın hangi scope’da aranacağını gösteren try bloğu, herhangi bir hatanın yakalanması durumunda çalışacak kodları belirleyen catch bloğu, ve her durumda çalışacak olan finally bloğudur. Catch blokları birden fazla olabilir. Örneğin : [java] public static void dosyaOku(String dosyaAdi) { try { FileReader fr = new FileReader(dosyaAdi); fr.read(); } catch (FileNotFoundException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } [/java] Bu örneğimizde FileReader yapıcı metodumuz FileNotFoundException istisnasını fırlatabilir, FileReader sınıfına ait read() metodu ise IOException türünden bir hata fırlatabilir. Bu iki hata için iki ayrı catch bloğu tanımlanmıştır. Burada dikkat etmemiz gereken nokta yakaladığımız exceptionlar arasında polymorfik bir ilişkinin bulunması durumunda hataların özelden genele yani türeyen exceptiondan ana exceptiona doğru yakalanmasıdır. Yukarıdaki örneğimizde bu durum mevcuttur. FileNotFoundException IOException’dan türediği için önce FileNotFoundException yakalanmalıdır aksi takdirde derleyici hata verecektir. Burada bir diğer dikkat edilecek husus try, catch ve finally blokları da kendilerine özgü bir scope oluştururlar. Yani try bloğu içinde tanımlanmış bir değişkene catch bloğu içinde ulaşmaya çalışırsanız derleyici hatası alırsınız. İstisnai Durumların Bildirilmesi : Yukarıdaki örneklerde istisnai durumların yakalanmasını kısaca öğrendik. İstisnalarla baş etmenin diğer bir yöntemi de istisna bildiriminde bulunmaktır. İstisna bildirimleri hataları bir üst seviyeye taşımak için kullanılır. Bu bildirimler throws anahtar kelimesiyle yapılır. İstisna bildirimleri metod imzasının sonuna throws anahtar kelimesinin ardına exception sınıf isimlarinin verilmesiyle yapılır. İkinci örneğimizi istisnayı yakalamak yerine bildirimde bulunmak suretiyle üst seviyeye delege edecek şekilde düzenleyelim : [java] public static void dosyaOku(String dosyaAdi) throws IOException,FileNotFoundException { FileReader fr = new FileReader(dosyaAdi); fr.read(); } [/java] Görüldüğü gibi metodumuz exception bildiriminde bulunduğu için istisnai durumları işlemek için herhangi bir kod yazmamıza gerek kalmadı. Kullanıcı Tanımlı İstisnai Durumlar : Kendi yazdığımız kütüphanelerde olsun, programlarda olsun kendimize özgü istisnai durumlar tanımlamak isteyebiliriz. Bunu yapmak için Exception sınıfından türeyen yeni bir sınıf tanımlamamız yeterli olacaktır. Hemen örnek bir kullanıcı tanımlı istisna ve kullanımını görelim : [java] package net.orhanbalci.tree.binarysearchtree; /** * * @author Orhan */ public class ItemNotFoundException extends Exception{ Comparable item; /** Creates a new instance of ItemNotFoundException */ public ItemNotFoundException(Comparable item) { this.item = item; } public String toString() { return “The item “+item+” could not be found in the tree”; } } [/java] Yukarıda tanımladığımız istisnai durumun kullanıldığı kod parçacığını görelim:

NetBeans İp Ucu : Herhangi bir sınıfın, metodun, üyenin proje içinde nerelerde kullanıldığını görmek için Alt + F7 tuş kombinasyonunu kullanabilirsiniz. Yada konteks menüsünden Find Usages (Kullanımları Bul) menü elemanını seçebilirsiniz.

[java] private BinaryTreeNode remove(BinaryTreeNode subTreeRoot, Comparable element) throws ItemNotFoundException { if(subTreeRoot == null) throw new ItemNotFoundException(element); …. } [/java] [ad#Yazi Ici Buyuk]