Java - Tüm hataları yakalamak

LifeMCServer

Nether Yerlisi
Mesajlar
2,410
En iyi cevaplar
98
Beğeniler
2,461
Puanları
10,250
Ruh hali
Tekrardan Merhabalar!
Başka bir konu ile karşınızdayım. Bu sefer ki konumuz ise Java'da tüm hataları yakalamak hakkında.
Öncelikle biraz basitten başlamak istiyorum:

Java Hataları Nedir?
Java da kritik sistem / JVM hataları dışında tüm hatalar Java kodunun içerisinde, standart java API'leri tarafından veya diğer kullanıcı tanımlı methodlar, kodlar tarafından atılabilir ve yakalanabilir. Atma işlemini throw kelimesi ile, yakalama işlemini ise try ve catch kelimeleri ile yapıyoruz.
Java:
try {
 throw new IllegalStateException("Bunu beklemiyorduk.");
} catch (final IllegalStateException e) {
 System.err.println("Beklenen bir hata oluştu (:");
 e.printStackTrace();
}


Throw özelliğini yukarıda ki gibi kullanarak bir hata çıkarabiliriz. Fakat eğer bu hatayı kimse yakalamaz ise ve "Uncaught Exception Handler" (Yakalanmayan Hata İşleyicisi) tarafından işlenmez ise bu hatamız görünmez bir hata olacaktır ve yürütülen kodu durdurmaktan başka bir iş yapmayacaktır.

Tüm Hataları Yakalamak
Yukarıda belirttiğim gibi java'da hataları atıp yakalayabiliyoruz, yakalama işlemi try ve catch kelimeleri ile oluyor. Try bloğuna yazdığınız kod yürütülür iken bir hata çıkar ise catch bloğu yürütülüyor, finally bloğu ise eğer eklediyseniz hata olsa da olmasa da yürütülüyor (return, break, continue vb yapsanız bile yürütülüyor). JavaScript ve C# gibi diller de direkt olarak catch {} veya catch(e) {} yapabilir iken Java'da yakalamak istediğimiz hatanın Java class ismini girmemiz gerekiyor. Bu durumda insanların aklında tüm hataları nasıl yakalayabiliriz gibi bir sorun beliriyor.

Başlamadan belirtelim;
Eğer bunu tüm hataları yakalayıp yok saymak için istiyor iseniz yapmamanız ve hataları izleyip çözmeye çalışmanız tavsiyem. Bu durumda stackoverflow sitesi sizin en büyük yardımcınız, aldığınız hataların caused by: kısmını veya hata açıklamasının / adının olduğu kısımları Google'a yazarak çıkan stackoverflow linklerinden potansiyel çözümlere ulaşabilirsiniz.

Java'da her şey bir class hiyerarşisine göre tasarlanmıştır, yani önceki konuda da anlattığım gibi tüm classlar (objeler) java.lang.Object classından türer. Mesela bu yüzden çeşidi Object olan bir variableye (değişkene) istediğimiz her şeyi ama her şeyi atayabiliriz, fakat bunun karşılığında o atadığımız değere spesifik methodları ve özellikleri kullanamayız. Çünkü Java'nın bizim ona "bu bir obje, güven bana" dediğimiz için girdiğimiz değerin spesifik methodları ve özellikleri hakkında bir bilgisi yok. Bu durumda biz sadece java.lang.Object classına ait methodları ve özellikleri kullanabiliriz.

Tüm Hataları Yakalamak - Throwable & Exception
Yukarıda belirttiğim hiyerarşide tüm hata classları java.lang.Throwable'dan türüyor, fakat bunu yakalamanız önerilmez çünkü bu OutOfMemoryError gibi kullanıcı kaynaklı kritik yakalanmaması gereken sistem hatalarını da içeriyor, bu yüzden genelde sadece java.lang.Exception'u yakalamanız yeterli olacaktır.

Uncaught Exception Handler Ayarlamak
Tüm hataların başka bir garanti yolu ise java'ya kendi yakalanmamış hata işleyicimizi kullanmasını söylemektir. Ama dikkatli olun eğer yakalanmayan hata işlenir iken hata çıkar ise daha kötü sonuçlar olabilir :D Her neyse yine de benim neredeyse her programımda yakalanmayan hataları işlemek için kullandığım ufak kodu aşağıya bırakıyorum.
Java:
final UncaughtExceptionHandler exceptionHandler = (thread, exception) ->
{
    System.err.println("Thread " + thread.getName() + " generated an exception:");
    exception.printStackTrace();
};

Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler);


Kodu eklemeniz gereken yer kodunuzun başladığı en baş nokta. Bu sayede program açıldıktan hemen sonra dahi oluşan yakalanmayan hataları görebileceksiniz. Önerim bu kodları main methodunun başına veyahut daha önceden çalışmaya başlamasını istiyor iseniz de static bloğuna koymanızdır.​

Kod Java 8 ve üstü gerektiriyor fakat eğer lambda (-> olan kısım) kısımlarını değiştirir iseniz eski versiyonlarda da sorunsuz çalışacaktır. Kodu geliştirmek için System.err#println ve java.lang.Throwable#printStackTrace methodlarını kendi logger kütüphanenizin methodları ile değiştirebilirsiniz.

Bu konumda Java'da basitçe hataları, try - catch'i ve tüm hataları nasıl yakalayabileceğimizi anlattım. Konunun başlığı "tüm hataları yakalamak" olduğu için daha çok ona odaklandım. Anlamadığınız veya sormak istediğiniz yerleri yorum olarak veya özel mesaj olarak atabilirseniz elimden geldiğince yardımcı olmak isterim.

Sonraki konularda görüşmek üzere, iyi forumlar..
 



Üst