Exception Handling In Java

Hikmet Çakır
6 min readJan 3, 2021

Öncelikle exception , run time’da bir kodda ortaya çıkan anormal bir durumdur.Başka bir değişle run time hatasıdır da diyebiliriz.

Exception handling’i desteklemeyen programlama dillerinde,hatalar manuel olarak kontrol edilmeli ve işlenmelidir.Tipik olarak hata kodları kullanılarak vb. yaklaşımlarla sürekli kontrol edilmelidir.Bu yaklaşımlar oldukça zahmetli ve külfetlidirde.

Java’da exception handling,bu sorunları önler ve süreçte çalışma zamanı hata yönetimini nesne yönelimli dünyaya getirir.Programımızda beklenmedik bir durum karşısında veya bir felaket durumunda kaybımızı minumuma çekmemize yardımcı olur.

Exception Handling Temelleri

Java’da exception,bir kod parçasında meydana gelen istisnai bir durumu tanımlayan bir nesnedir.Exception içeren bir durum ortaya çıktığında,bu exception’ı temsil eden bir nesne oluşturulur ve hataya neden olan yöntemde atılır.

İlgili method , exception’nın kendisini ele almayı veya aktarmayı seçebilir.Her iki durumdada , bir noktada exception yakalanır ve işlenir.Exception’lar Java run-time systemda üretilebilir veya kodunuz manuel olarak oluşturabilir.

Java tarafından atılan(thrown) exceptionlar , Java dilinin kurallarını veya Java execution environment kısıtlamalarını ihmal eden temel hatalarla ilgilidir.

Manual oluşturulan exceptionlar genellikle bir yöntemi çağıran kişiye bazı hata durumlarını bildirmek için kullanılır. Java’da exception handling 5 keyword ile yönetilir:

  • try
  • catch
  • throw
  • throws
  • finally

Kısaca şöyle çalışıyorlar,exceptionlar için monitör etmek istediğiniz(izlemek istediğiniz) program statementları bir try bloğu içinde yer alır.try bloğu içinde bir exception olursa,atılır.

Kodunuz bu exceptionu yakayılabilir(catch kullanarak) ve birkaç mantıklı tavır ile handle edebilir.Sistem tarafından oluşturulan exceptionlar,java run time tarafından otomatik olarak atılır.

Manuel olarak bir exceptionda atabiliriz throw keywordunu kullanarak.Bir methoddan atılan herhangi bir exception,bir throws keywordu ile belirtilir.

Bir try bloğu tamamlandıktan sonra kesinlikle execute edilmesi gereken bir kod,bir finally bloğuna yerleştirilir.

try{
//block of code to monitor for errors
}catch(ExceptionType1 exOb){
//exception handler for ExceptionType1
}catch(ExceptionType2 exOb){
//exception handler for exception type2
}
//...
finally{
//block of code to be executed after try block ends
}

Exception Tipleri

Tüm exception türleri throwable built in classının subclasslarıdır.Böylece throwable , exception class hierarchsinin en üstündedir.

throwable’ın hemen aşağısında,exceptionları 2 farklı dala bölen 2 alt sınıf vardır.Bir branch Exception ile yönetiliyor.Bu sınıf ,kullanıcı programlarının yakalaması gereken istisna koşullar için kullanılır.Bu aynı zamanda kendi özel exception typelarınızı oluşturmak için alt sınıflara ayıracağınız classdır.

Exceptionın önemli bir subclassı vardır. RuntimeException diye çağrılır.Bu tür exceptionlar,yazdığınız programlar için otomatik olarak tanımlanır ve sıfıra bölme ve geçersiz dizi indexleme gibi şeyleri içerir.

Diğer branchin tepesinde Error vardır.Programınız tarafından normal koşullar altında yakalanması beklenmeyen istisnaları tanımlar.Error tipi exceptionlar,Java run-time system tarafından,çalışma zamanını ortamının kendisi ile ilgili hataları belirtmek için kullanılır.

Ex : Stackoverflow böyle bir hataya örnektir.,

Şimdi öncelikle programımızdaki exceptionları nasıl handle edeceğinizi öğrenmeden önce,onları handle etmezsek ne olacağını öğrenmek yararlı olacaktır.Alttaki küçük program kasıtlı olarak devide-by-zer error içerir.

class Exc0{
public static void main(String args[]){
int d = 0;
int a = 42 / d;
}
}

Java run time sistem sıfıra bölme girişimini algıladığında,yeni bir istisna nesnesi oluşturur ve ardından bu exception’ı atar.

Bu Exc0'ın yürütülmesinin durmasına neden olur,çünkü bir exception atıldığında,bir exception handler tarafından yakalanmalı ve hemen ele alınmalıdır.

Bu örnekte kendi exception handlerımızı sağlamadık.Bu nedenle istisna,java runtime sistemi tarafından sağlanan varsayılan default handler tarafından yakalanır.Default handler,exception açıklayan bir string görüntüler.Exceptionın oluştuğu noktadan itibaren bir stack trace yazdırır ve programı sonlandırır.

Bu örnek çalıştırıldığında istisna

java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
  • class adı : Exc0
  • method adı : main
  • dosya adı Exc0.java
  • satır numarası 4'ün

Burada üstte belirtilen ifadenin basic stack trace’e nasıl dahil edildiğine dikkat edelim.Bununla beraber atılan exception türünün ArithmeticException adlı bir Exception alt sınıfı olduğuna dikkat edin,bu da ne tür bir hata olduğunu daha spesifik olarak açıklar.Üretilebilecek run time hataları.

Stack trace hataya neden olan yöntem çağrılarının sırasını gösterir.Örneğin aşağıda aynı hatayı main()’den ayrı bir yöntemle ortaya çıkaran başka bir programın başka bir sürümü var.

class Exc1{
static void subroutine(){
int d = 0;
int a = 10 / d;
}
public static void main(String args[]){
Exc1.subroutine();
}
}

Varsayılan exception handlerdan elde edilen stack trace,tüm çağrı yığının nasıl görüntülendiğini gösterir.

java.lang.ArithmeticException: / by zero
at Exc1.subroutine(Exc1.java:4)
at Exc1.main(Exc1.java:7)

Burada görüldüğü üzere,yığının alt kısmı main satırı 7'dir,bu subroutine metodudur ve 4.satırda exceptiona neden olur.

Stack trace ,hata ayıklama için oldukça kullanışlıdır çünkü hataya yol açan adımların kesin sırasını belirler.

Using try and catch

Java run-time system tarafından sağlanan default exception handler hata ayıklama için yararlı olsada Genelde bir exceptionı kendimiz halletmek istiyicez.Bunu yapmamız 2 yarar sağlar.

1-Hatayı düzeltmemize olanak sağlar.
2-Programın otomatik olarak sonlanmasını engeller

Şimdi alttaki kodu inceliyelim üstüne konuşalım.

class Exc2{
public static void main(String args[]){
int d,a;
try{
d=0;
a=42/d;
System.out.println("This will not be printed");
}catch(ArithmeticException e){
System.out.println("Division by zero");
System.out.println("After catch statement.");
}
}
}

Burada 0'a bölme yapılmış.Bunu try catch mekanizmasıyla yakalıyoruz.Burada şuna değinmeliyim catch keywordunun kapsamı,exception durumunu çözmek ve ardından hata hiç olmamış gibi devam etmek olmalıdır.

Burada direk Exception yaparakda çözülebilirdi ama bu pek sağlıklı olmazdı.Çünkü gerek kodun okunabilirliği gerek sürdürülebilirliği gibi birçok sebepten ilerki zamanlarda problem oluşturma olasılığı bir hayli yüksek olucak.

Şimdi başka bir örneği inceliyelim.

import java.util.Random;class HandleError{
public static void main(String args[]){
int a=0,b=0,c=0;
Random r = new Random();
for(int i=0 ; i < 32000 ; i++){
try{
b = r.nextInt();
c = r.nextInt();
a = 12345 / (b/c);
}catch(ArithmeticException e){
System.out.println("Division by zero.");
a = 0;
}
System.out.println(" a : "+a);
}
}
}

Exception’ın Tanımlanması Ve Gösterilmesi

Throwable , toString() metodunu override eder bu yüzden exceptionın tanımı bir string içerir.İstersek hatayı basit bir argüman olarak geçirebiliriz println kullanarak yazdırabiliriz.

catch (ArithmeticException e) {  
System.out.println("Exception: " + e);
a = 0; // set a to zero and continue
}
Exception: java.lang.ArithmeticException: / by zero

Multiple Catch Clauses

Bazı durumlarda tekbir kod parçasıyla birden fazla exception oluşabilir.Bu durumla 2 veya daha fazla catch clause koyabilirsin.Bununla beraber catchlerde alt classlar super classlardan önce gelmelidir yoksa program hata verir.Unreachable kod kabul edilemez.

class MultipleCatches{
public static void main(String args[]){
try{
int a = args.length;
System.out.println("a = "+a);
int b = 42/a;
int c[] = { 1 };
c[42] = 99;
}catch(ArithmeticException e){
System.out.println("Divide by 0: "+e);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array index oob: "+e);
}
System.out.println("After try/catch blocks.");
}
}

Javada unreachable code bir hatadır.

throw

ThrowableInstance ,Throwable tipinde bir obje olmak zorundadır veya trowableın bir alt classı (subclass)

class ThrowDemo {  
static void demoproc() {
try {
throw new NullPointerException("demo");
}catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
}
}
public static void main(String args[]) {
try {
demoproc();
}
catch(NullPointerException e) {
System.out.println("Recaught: " + e);
}
}
}

throws

eğer bir method handle edemediği bir exceptiona sahipse bunu belirtmesi gerekir.Böylece methodu kullananlar kendilerini bu exceptiona karşı koruyabilir.
Bunu methodun bildirimine bir throws keywordu ekleyerek yapabiliriz.
Bir throws keywordu ,bir methodun atabileceği istisna türlerini listeler.
Bu , Error ve RuntimeException türündeki exceptionlar veya bunların alt sınıflarından herhangi biri dışında tüm istisnalar için gereklidir.

Şayet methodda bir exception fırlatıldığı halde methodda belirtmezsek bunu kodumuz compile edilmez.

class ThrowsDemo{
static void throwOne() throws IllegalAccessException{
System.out.println("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]){
try{
throwOne();
}catch(IllegalAccessException e){
System.out.println("Caught "+e);
}
}
}
}

finally

Exceptionlar thrown edildiğinde,bir methoddaki execute ,method boyunca normal akışı değiştiren oldukça ani,nonlinear bir yol alır.Methodun nasıl kodlanıldığına bağlı olarak,bir exceptionın methodun vaktinden önce dönmesine neden olması bile mümkündür.Bu bazı yöntemlerde sorun olabilir.

Örneğin bir methodun girişte bir dosyayı açarsa ve çıkışta onu kapatırsa,dosyayı kapatan kodun istisna işleme mekanizması tarafından atlamasını istemezsiniz.finally keywordu bu olasılığa hitap etmek için tasarlanmıştır.

class FinallyDemo{
static void procA(){
try{
System.out.println("inside procA");
throw new RuntimeException("demo");
}finally{
System.out.println("procA's finally");
}
}
}
}

Kabaca Java’daki Error Handling yapısına değindim umarım faydalı olabilmişimdir.Alta bir kaç link bırakıyorum boş zamanlarınızda izleyip yeni bilgiler öğrenebilir veya mevcut bilgilerinizi pekiştirebilirsiniz :]

Link 1 : https://www.youtube.com/watch?v=K_-3OLkXkzY

Link 2 : https://www.youtube.com/watch?v=xNVlq9IEBEg

Link 3 : https://www.youtube.com/watch?v=SjKtOu1iZuo

--

--