Bu Sayfayı Paylaş:

Kavram

Runtime Exception

Tanım: Programın çalışması esnasında oluşabilecek hata

Veri

Java'da Try-Catch Yapısı

Java'da genel bir exception yakalama (try-catch) yapısı
java'da genel bir exception yakalama (try-catch) yapısı aşağıdaki gibidir :
try{
	// Bir şeyler yap	
}catch(AException e){
	// A tipi Exception Oluştu
}catch(Exception e){
	// B tipi Exception Oluştu
}finally{
	// Her zaman bazı işleri yap
}

Programın çalışması sırasında try bloğu içerisinde AException oluşur ise catch(AException e){} bloğu içerisindeki kod çalışır ve ardından finally bloğu içerisindeki kod çalışır. Eğer try bloğu içerisinde genel bir Exception oluşur ise catch(Exception e){} bloğu çalışır ve ardından finally bloğu çalışır. Eğer herhangi bir hata olmaz ise en son finally bloğu çalışır.

Örnek

Java'da Throws Örneği

Java basit bir throws kullanım örneği
Aşağıda java basit bir throws kullanım örneği görülmektedir :
public Person getStudent(String number)
	throws StudentNotFoundException
{
	//...
}

getStudent() yöntemi StudentNotFoundException fırlatmaktadır. Bunu belirtmek için yöntem tanımından sonra throws StudentNotFoundException ifadesi yazılmıştır.

Kavram

ClassNotFoundException

Tanım: Java'da çalışma anında bir sınıfın yüklenmeye çalışıldığı sırada bulunamaması (jaba classpath'te arar) sonucu oluşan exception ve bu exception'ın sınıfı. Class.forName() , ClassLoader.loadClass(), ClassLoader.findSystemClass() metodları bu exception'ı fırlatmaktadır

Kavram

NoClassDefFoundError

Tanım: Java'da çalışma anında bir sınıfın bulunamaması veya doğru bir şekilde okunamadığı veya yüklenemediği zamanlarda alınan hata. Sınıfın bulunamaması veya onun bağlı olduğu başka bir sınıfın bulunamamasında da bu hata alınır

Veri

ClassNotFoundException JavaDoc Açıklaması

ClassNotFoundException javadoc içindeki açıklaması aşağıdaki gibidir:

Thrown when an application tries to load in a class through its string name using:
The forName method in class Class.
The findSystemClass method in class ClassLoader .
The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found

Veri

NoClassDefFoundError JavaDoc Açıklaması

NoClassDefFoundError için javadoc içindeki açıklama aşağıdaki gibidir :

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

Veri

ClassNotFoundException ve NoClassDefFoundError Arasındaki Farklar

ClassNotFoundException ve NoClassDefFoundError arasındaki farklar aşağıdaki gibi özetlenebilir :
  • ClassNotFoundException bir Exception'dır , NoClassDefFoundError ise bir Error'dur ve LinkageError sınıfından türer
  • ClassNotFoundException verilen bir sınıfın classpath'te bulunmadığı zaman Class.forName() , ClassLoader.loadClass(), ClassLoader.findSystemClass() gibi metodlardan fırlatılır. NoClassDefFoundError ise Java Virtual Machine tarafından, bir sınıfın tanımının yükleyemediği (örneğin kurucunun veya içinde tanımlanmış static bloğun yüklenememesi, sınıfı bulanamaması, sınıfın bağımlı olduğu başka sınıfların bulunaması, uyumsuz versiyon, sınıfın formatının kötü olması) zaman oluşturulur

Veri

MultiCatch Exception

Java 7 ile birlikte catch bloğunda birden fazla Exception yakalanabilmektedir. Eski yöntemde aşağıdaki gibi olacaktır :
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MultiCatchException {

	public static void main(String[] args) {

		try {
			File f1 = new File("c:\\date.txt");
			FileReader fis = new FileReader(f1);
			BufferedReader reader = new BufferedReader(fis);
			String line = reader.readLine();
			SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyy");
			Date date = format.parse(line);
			System.out.println("dosyadaki date okundu");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	   		
	}

}
Örnek FileNotFoundException ve IOException fırlatmasından dolayı ayrı ayrı catch bloğu yazılmıştır. ParseException içinde catch bloğu eklenmiştir. Java 7 ile birlikte aşağıdaki gibi aynı örnek yazılabilir :
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MultiCatchException {

	public static void main(String[] args) {

		try {
			File f1 = new File("c:\\date.txt");
			FileReader fis = new FileReader(f1);
			BufferedReader reader = new BufferedReader(fis);
			String line = reader.readLine();
			SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyy");
			Date date = format.parse(line);
			System.out.println("dosyadaki date okundu");
		}catch (IOException  | ParseException e) {
			e.printStackTrace();
		}
	   		
	}

}
FileNotFoundException zaten bir IOException olmasından dolayı yazılmasına gerek yoktur. Exception'lar aralarına pine (|) işareti koyularak ayrılmıştır. Görüldüğü birden fazla catch kullanılmamıştır.

Alıntı

Java Exception

Java’da Throwable ana sınıfı ile exception tanımlanır ve üç alt sınıf ile exception’lar farklı anlamlar kazanır: Error, Exception, RuntimeException
Sahipleri : Yusuf Boyacıgil
Bu yazı izinle alıntılanmıştır : http://yboyacigil.com/turkish/java/java-exceptions/
On küsür yıldır Java’da program yazan biri olarak exception’lar baş belası mı yoksa nimet mi anlayabilmiş değilim. Sanırım bunun basit, tek bir cevabı yok. Her an ikisinden birine dönüşebilir. :)
Exception’ı daha iyi algılamak/anlamlandırmak için İstisna ya da İstisnai Durum diye mi adlandırmalıyım? Bu ve bunun gibi ithal ettiğimiz (herşeyi ediyoruz ya!) kavramları bir kelime ile ifade etmek sanıldığı kadar kolay değil! Şundan eminim ki ortalama bir bilgisayar programcısının, exception dendiğinde kafasında üç aşağı beş yukarı şöyle bir algı oluşuyor: Bir metodu kodlarken, metodun normal akışını bozan bir durumdur exception. Mesela: bir dosyayı okumak istiyoruz ama öyle bir dosya yok. Bu tür durumları ifade etmek, oluştuğunda çaresine bakmak veya birilerinin bakmasını sağlamak için programlama dilleri bir takım araç veya yapılar tanımlamışlardır.
Yukarıda yaptığım tanımı yeterli kabul ederek, bundan sonra exception demek koşuluyla, Java’da exception’lar ile ilgili anlatmak istediklerime geçebilirim.
İlk olarak anlatacaklarıma temel oluşturması için Java penceresinden bakıldığında exception nasıl birşeydir, exception’larla nasıl çalışırız basit olarak açıklayayım:
Java’da Throwable ana sınıfı ile exception tanımlanır ve üç alt sınıf ile exception’lar farklı anlamlar kazanır: Error, Exception, RuntimeException.

Error


Java Virtual Machine (JVM)’e havale edilmesi gereken ve her ne kadar mümkün olsa da program içerisinde müdahele etmenin gereksiz olduğu durumu ifade eder. Mesela: OutOfMemoryError program için ayrılan hafızanın tükendiğini gösterir. Hafıza olmadan ne yapılabilir ki? Error durumunda uygulamanın kapatılması gerekir.

Exception


Çaresine program içerisinde bakılabilecek durumları ifade eder. Mesela bir işi yapmak için veritabanına bağlanmanız gerekiyor, ağ sorunu yüzünden bağlanamadığınız veya bağlandınız ama diyelim işlemi yaparken bir veritabanı tablosuna ait kısıtı bozdunuz. Sizin veya sizin yazdığınız metodu çağıran kişinin alabileceği bir takım aksiyonlar olabilir: bağlantı sorunu varsa tekrar denemek, bunu kullanıcıya raporlamak ya da kısıtı bozan durumu anlayıp, bozmayacak şekilde yeniden istekte bulunmak gibi.

RuntimeException


Program çalışırken, erişilen bir değişkenin null olması, veya bir dizinin var olamayan bir indeks’teki elemanına erişmek gibi telafisi olmayan durumları ifade eder. Bunlar için çoğu zaman bir aksiyon almanız gerekmez. Programın böyle bir durumda işine devam etmemesi gerekebilir.
Programı kodlarken exception’ları fırlatırız (throw), bizim çağırdığımız başka bir metod fırlatır (throws), onları yakalarız ve çaresine bakarız (try-catch-finally). Bunları Java anlatan kitaplara bırakarak asıl anlatmak istediğim meseleye geçiyorum.
Error’ları JVM’e havale ettiğimizde, geriye: Exception ve RuntimeException kalır. Ve bu iki exception (ve tabiki bunların alt sınıfları) sırasıyla kontrollü (checked) ve kontrolsüz (unchecked) exception diye bilinirler.
Kontrollü olması programı daha yazarken bunların yakalanması ve icabına bakılması veya tekrar fırlatılmasını gerektirir.
Kontrolsüz exception’ları yakalamak zorunluluğu yoktur, ama oluştuğunda çaresine de bakılması gerekebilir.
Yani birinde herşeyi kontrol etme ve bunun getirdiği yük, diğerinde hiçbir şey kontrol etmeme lüksü öte yandan oluşmaması için bir çaba harcanması gerekliliği var. Şöyle de bir durum var ki eğer kimse yakalamazsa JVM bunu yakalayıp, programı sonlandırabilir.

Kontrollü mü kontrolsüz mü olsun?


Kodlarken ne zaman kontrollü ne zaman kontrolsüz exception kullanmamız gerekir? Kontrollü ve kontrolsüz kullanmanın bir ayarı var mı ve bu ayar kaçarsa ne olur? Kodlarken bu ikilemden nasıl kaçarız?
Bu konuya kafa yoranlar veya bundan dolayı ağzı yananlar, bazı kurallar koyarak bunun üstesinden gelebiliriz demişler. Yani:
  • Kontrollü exception’ları, metodu kodlarken, çağıran kişi oluştuğunda çaresine bakabileceğine inanıyorsanız kullanabilirsiniz.
  • Gereksiz yere kontrollü exception kullanmaktan kaçınınız.
  • Kontrolsüz exception’ları metodun olmazsa olmaz ön koşullarını kontrol etmek için kullanırsanız iyi olur.
gibi.
Son zamanlarda kontrollü exception’ları kullanmama, yerine kontrolsüz exception’larla gitme yönünde bir eğilim var. Örnegin Spring, Hibernate geliştiricileri kontrollü exception kullanmaktan vazgeçmiş durumdalar. C#’da kontrollü exception diye birşey yok. Bunun sebepleri var elbette:
  • Kontrollü exception’lar yakalanmak veya fırlatılmak zorunda olduğu için ya kodun okunmasını güçleştiriyor (bir yada daha çok try-catch blokları ile) ya da metod tanımında bu exception’ların tek tek yazılması gerekiyor. Metodu çağıran başka metodlar ya bunları yakalamak ya da tekrar fırlatmak durumunda kalıyorlar.
  • Özellikle son programlarda kullanılmak üzere hazırlanan ara ürünler (Framework, API gibi) kontrollü exception’lar yüzünden sonraki versiyonlarda sıkıntı yaşayabiliyorlar. Nasıl mı? Mesela ilk sürümde foo diye A, B, C exception’larını atan bir metod tanımlı, ikinci sürümde foo metoduna yeni bir özellik eklediniz ve bu da D diye bir exception daha eklemenizi gerektirdi metodun tanımına. Bu durumda ilk sürümü kullanan kişi ikinci sürüme direkt olarak geçemiyor. Çünkü D exception’ını da yakalaması gerekir.
Şunu da not etmemiz gerekir ki sadece biri veya ötekiyle gitmek zorunluluğu yok. İhtiyacınıza göre her ikisini kullanmanız gerekebilir. Sadece kullanırken burada bahsi geçen konuları göz önüne alıp bir karar verebilirsiniz.
Ben, exception’larla çalışırken, bu tür ikilemlerle çok karşılaşıyorum ve genellikle şu şekilde üstesinden geliyorum:
  • Zorunda kalmadıkça kontrollü exception kullanmamak, kontrolsüz exception’larla gidebildiğim kadar gitmek.
  • Var olan kontrolsüz exception’ları (IllegalArgumentException, IllegalStateException, NullPointerException, vs) kullanmak ve gerekmedikçe kendi exception sınıfımı uydurmaktan kaçınmak.
  • Eğer bir exception sınıfı tanımladıysam, onu yakalayana çaresine bakması için gerekli tüm bilgileri aktarmak ve ekstra yardımcı olabilecek metodlarla exception sınıfını zenginleştirmek.
  • Exception’ların mümkün mertebe en üst katmanda yakalanması için uğraşmak, daha alt katmanlarda gerekmedikçe bir exception’ı yakalamamak.
  • Programın veya program thread’lerinin yakalanmamış bir exception yüzünden kapanmaması için gerekli aksiyonları almak.
  • Kontrolsüz exception’ları javadoc ile yanlış anlaşılmaya izin vermeyecek şekilde açıklamak
Bu konuyla alakalı başka (ingilizce) kaynaklar:



Bu Sayfayı Paylaş:

İletişim Bilgileri

Takip Et

Her Hakkı Saklıdır. Bu sitede yayınlanan tüm bilgi ve fikirlerin kullanımından fibiler.com sorumlu değildir. Bu sitede üretilmiş , derlenmiş içerikleri, fibiler.com'u kaynak göstermek koşuluyla kendi sitenizde kullanılabilirsiniz. Ancak telif hakkı olan içeriklerin hakları sahiplerine aittir