Logo
Ana Sayfa
ÖZEL KODLAMA DERSLERİ
Yazılım Özel Ders
Tüm birebir programlara genel bakış
Python Yazılım Kursu
Sıfırdan ileri seviyeye birebir Python
Java Yazılım Kursu
OOP odaklı birebir Java eğitimi
AP Computer Science Principles
AP CSP sınav hazırlığı
GRUP DERSLERİ
Python & Django Masterclass
SINIRLI KONTENJAN
Java & Spring Boot Masterclass
SINIRLI KONTENJAN
C# .NET Masterclass
SINIRLI KONTENJAN
VİDEO DERSLER
Sıfırdan Temel Python Kursu
Kendi Hızında Öğren
ÜCRETSİZ
Seviye Testi
Ücretsiz — Python, Java, algoritma seviye testleri
Kariyerini Keşfet
Sertifika Doğrula
Belge numarası ve soyad ile doğrulama

Java'da Checked ve Unchecked Exception Ayrımı: Doğru Karar Nasıl Verilir?

Yazar: Berk Keskin 24.08.2026 ~12 dk okuma 8 Okunma
java-checked-unchecked-exception-farki

Java'da checked ve unchecked exception ayrımı, bir hatanın derleyici tarafından zorunlu tutulup tutulmadığına bakılarak yapılır: checked exception'lar throws ile bildirilmek ya da try-catch ile yakalanmak zorundadır, unchecked exception'lar ise RuntimeException soyundan geldiği için böyle bir zorunluluk taşımaz. Karar verirken temel ölçüt şudur: hata, çağıran kodun önceden bilip yönetmesi gereken beklenen bir durum mu, yoksa bir programlama hatasının sonucu mu? Bu makalede java exception hiyerarşisinden başlayarak bu ayrımı somut örneklerle netleştireceğiz.

Java'da Exception Hiyerarşisi: Throwable, Exception, RuntimeException ve Error

Java'nın hata yönetim mimarisini anlamak için önce hiyerarşinin tepesine bakmak gerekir. Tüm fırlatılabilir (throwable) nesnelerin ortak atası Throwable sınıfıdır ve bu sınıftan iki ana dal türer: Exception ve Error. Bu iki dal, birbirinden tamamen farklı sorumluluk alanlarını temsil eder ve karışıklık genellikle bu ayrımın netleştirilmemesinden kaynaklanır.

Hiyerarşiyi basit bir şema üzerinden özetlemek, konunun zihinde oturmasını kolaylaştırır:

  • Throwable — tüm hata ve istisnaların kök sınıfı
  • Exception — programın normal akışında karşılaşılabilecek istisnai durumlar
    • Checked exception'lar — IOException, SQLException gibi, RuntimeException dışında kalan tüm alt sınıflar
    • RuntimeException dalı (unchecked) — NullPointerException, IllegalArgumentException gibi programlama hatalarını yansıtan sınıflar
  • Error — JVM seviyesinde oluşan, programcının kontrolü dışındaki ciddi durumlar (StackOverflowError, OutOfMemoryError)

Bu şemadan çıkan pratik sonuç şudur: Exception dalı altında yer alan her şey "checked" değildir; yalnızca RuntimeException soyundan gelmeyenler checked kabul edilir. RuntimeException da aslında Exception'ın bir alt sınıfıdır, ama derleyici onu farklı muamele eder ve bildirim zorunluluğu getirmez.

Error sınıfı ise tamamen ayrı bir kategoridir. Bir uygulamanın yığın belleğinin taşması (StackOverflowError) ya da JVM'in bellek yetersizliği yaşaması (OutOfMemoryError) gibi durumlar, kodun mantığından değil, çalışma zamanı ortamının fiziksel sınırlarından kaynaklanır. Bu tür durumların yakalanıp normal akışa devam edilmesi genellikle beklenmez ve tavsiye edilmez; çünkü sistemin o anki kararlılığı zaten şüphelidir. Bu üç katmanı — checked exception, unchecked exception ve Error — birbirinden ayırt edebilmek, Java'da sağlam hata yönetimi kurmanın ilk adımıdır. Bu ayrımı ne kadar netleştirdiğinizi görmek isterseniz Java bilgi seviyeni ölçen ücretsiz test üzerinden kendinizi sınayabilirsiniz.

Checked Exception Nedir? Derleyici Neden Zorunlu Kılar

Checked exception, Java derleyicisinin kodu derlemeden önce mutlaka ele alınmasını dayattığı istisna türüdür. Bir dosya okuma işlemini ele alalım: FileReader sınıfını kullanan bir metot, dosyanın bulunmaması ihtimaline karşı IOException fırlatabilir. Bu metodu çağıran kod, ya bu istisnayı try-catch bloğuyla yakalamak ya da kendi imzasına throws IOException ekleyerek sorumluluğu bir üst katmana devretmek zorundadır. Aksi halde kod derlenmez.

Bu zorunluluk keyfi bir kısıtlama değildir; belirli bir tasarım amacına hizmet eder. Derleyici, dış kaynaklarla etkileşime giren (dosya sistemi, ağ bağlantısı, veritabanı) işlemlerin başarısız olabileceğini bildiği için, bu ihtimali görmezden gelmenizi engeller. Amaç, çağıran kodun hatayı önceden bilerek ve bilinçli bir strateji kurarak yönetmesini sağlamaktır. Bir dosya bulunamadığında kullanıcıya anlamlı bir mesaj mı gösterilecek, işlem yeniden mi denenecek, yoksa varsayılan bir değere mi düşülecek — bu kararı derleyici sizin adınıza almaz ama böyle bir karar almanızı zorunlu kılar.

public String dosyaOku(String yol) throws IOException {
    try (BufferedReader reader = new BufferedReader(new FileReader(yol))) {
        return reader.readLine();
    }
}

Bu örnekte throws IOException ifadesi, metodu çağıran her geliştiriciye açık bir uyarı niteliği taşır: "bu işlem başarısız olabilir, buna hazırlıklı ol." Bu nedenle checked exception'lar zamanla bir API sözleşmesinin parçası haline gelir. Bir kütüphane veya servis metodunun imzasında yer alan checked exception, o metodun hangi hata senaryolarını açıkça beyan ettiğini gösterir; dokümantasyonun ötesinde, derleyici tarafından denetlenen bir garanti sunar. Bu yüzden checked exception tasarımı yaparken metodun imzasını değiştirmenin geriye dönük etkilerini de hesaba katmak gerekir, çünkü imzaya eklenen her yeni checked exception, o metodu çağıran tüm kodları etkiler.

Unchecked Exception Nedir? RuntimeException ve Programlama Hataları

Unchecked Exception Nedir? RuntimeException ve Programlama Hataları

Unchecked exception'lar, RuntimeException sınıfından türeyen ve derleyicinin bildirim ya da yakalama zorunluluğu getirmediği istisnalardır. Bir metot bu tür bir istisna fırlatabilir ama bunu throws ile belirtmek zorunda değildir; kod, bu olasılık göz ardı edilse bile sorunsuz derlenir.

Bu kategorinin en tanıdık örnekleri, çoğunlukla bir programlama hatasının doğrudan sonucudur. NullPointerException, kontrol edilmemiş bir referansın null olduğu durumda ortaya çıkar; ArrayIndexOutOfBoundsException ise bir dizinin sınırları dışında bir indekse erişilmeye çalışıldığını gösterir. Her iki durumda da hata, dış bir kaynağın öngörülemez davranışından değil, kodun mantığındaki bir eksiklikten kaynaklanır:

  • NullPointerException — bir nesne referansı kullanılmadan önce null kontrolü yapılmamış
  • ArrayIndexOutOfBoundsException — döngü sınırı veya indeks hesaplaması hatalı kurgulanmış
  • IllegalArgumentException — metoda geçersiz bir parametre değeri gönderilmiş
  • ArithmeticException — sıfıra bölme gibi matematiksel olarak tanımsız bir işlem yapılmış

Bu istisnaların ortak noktası, genellikle kodu düzelterek önlenebilir olmalarıdır; yakalayıp yönetmek yerine kaynağında engellemek çoğu zaman daha doğru yaklaşımdır. Bir null kontrolü eklemek ya da dizi sınırlarını doğru hesaplamak, bu istisnayı try-catch ile sarmalamaktan daha kalıcı bir çözümdür.

Unchecked exception'ların her metot imzasına eklenmemesinin de mantıklı bir gerekçesi vardır. Eğer NullPointerException veya ArrayIndexOutOfBoundsException gibi istisnaların her biri throws ile bildirilmek zorunda olsaydı, neredeyse her metot imzası uzun ve okunması güç bir istisna listesiyle dolardı; çünkü bu tür hatalar teorik olarak neredeyse her satırda oluşabilir. Bu durum, gerçekten önemli olan ve çağıranın bilinçli bir kararla ele alması gereken checked exception'ların da gözden kaçmasına yol açardı. Bu yüzden Java tasarımcıları, programlama hatalarını temsil eden istisnaları derleyici denetiminin dışında tutmayı tercih etmiştir; bu istisnaların ele alınma sorumluluğu, kodun kalitesine ve savunmacı programlama alışkanlıklarına bırakılmıştır.

Checked mi Unchecked mi? Karar Verirken Kullanılacak Pratik Ölçüt

Bir exception sınıfı tasarlarken "bu checked mi olsun, unchecked mi?" sorusunun cevabı kişisel tercihe değil, hatanın doğasına bakılarak verilir. Sektörde kabul gören yaklaşım, kararı tek bir soruya değil, sırayla uygulanan birkaç ölçüte dayandırır. Aşağıdaki adımlar bu kararı netleştirmek için kullanılabilir.

  1. Çağıran kod bu durumdan makul biçimde kurtulabilir mi? Ağ bağlantısının kopması, dosyanın bulunamaması ya da veritabanı bağlantısının zaman aşımına uğraması gibi durumlarda çağıran kod genellikle bir alternatif izleyebilir: tekrar deneyebilir, kullanıcıya farklı bir seçenek sunabilir veya işlemi güvenli şekilde iptal edebilir. Telafi mümkünse checked exception adaydır.
  2. Hata bir programlama hatası mı, yoksa kurtarılamaz bir durum mu? Negatif bir dizi indeksine erişmek, null bir referans üzerinde metot çağırmak veya geçersiz bir argüman göndermek kodun mantığında bir kusur olduğunu gösterir. Bu tür durumlar çalışma zamanında "yakalanıp devam edilecek" bir senaryo değil, geliştirme aşamasında düzeltilmesi gereken bir hatadır; bu yüzden unchecked olarak modellenir.
  3. Hatanın tekrar denenmesi, loglanması ya da kullanıcıya anlamlı bir mesajla bildirilmesi mantıklı mı? Eğer çağıran taraf hatayı aldığında somut bir aksiyon alacaksa (yeniden bağlanma, farklı bir kaynağa yönlenme, kullanıcıyı bilgilendirme) bu, exception'ın API sözleşmesinin görünür bir parçası olması gerektiği anlamına gelir; bu da checked exception'ı işaret eder.

Bu üç adım somut örneklere uygulandığında karar kendiliğinden netleşir. Bir ağ bağlantısı koptuğunda çağıran kodun tekrar deneme, farklı bir sunucuya bağlanma veya kullanıcıyı bilgilendirme gibi gerçek seçenekleri vardır; bu yüzden bu durum checked exception ile modellenir ve throws bildirimiyle görünür kılınır. Buna karşılık negatif bir dizi indeksiyle erişim denemesi, kodun daha yazılırken hatalı olduğunu gösterir; çağıran tarafın bu durumdan "kurtulması" değil, geliştiricinin kodu düzeltmesi beklenir, dolayısıyla unchecked exception olarak bırakılır. Bu ayrımı canlı örnekler üzerinden pekiştirmek isteyenler için birebir Java ders programı kapsamında gerçek proje senaryoları üzerinde exception tasarımı adım adım incelenebilir.

Sık Yapılan İki Hata: Aşırı RuntimeException ve Aşırı Checked Kullanımı

Sık Yapılan İki Hata: Aşırı RuntimeException ve Aşırı Checked Kullanımı

Java'da exception tasarımında en sık karşılaşılan sorunlardan biri, tüm hataları RuntimeException'a çevirerek işi kolaylaştırma eğilimidir. Bu yaklaşımda derleyici hiçbir zorunluluk getirmediği için geliştirici hızlıca yazıp geçer, ancak bunun bedeli sonradan ödenir: çağıran kod, metodun hangi hataları fırlatabileceğinden habersiz kalır. Metot imzası herhangi bir ipucu vermediği için hata yönetimi görünmez hâle gelir ve prodüksiyon ortamında beklenmedik anlarda uygulama çöker. Özellikle harici bir servise bağlanan, dosya okuyan veya kullanıcı girdisiyle çalışan kodlarda bu alışkanlık, hatanın fark edilmesini yalnızca test kapsamına veya şansa bırakır.

Diğer uçta ise tam tersi bir hata vardır: her olası durumu checked exception olarak modellemek. Bu durumda metot imzaları uzun throws listeleriyle dolar, her çağrı noktası zincirleme try-catch bloklarıyla kuşatılır ve kod okunabilirliği ciddi biçimde bozulur. Geliştiriciler çoğu zaman bu karmaşıklıktan kurtulmak için catch bloğunu boş bırakır veya hatayı sessizce yutar; bu da checked exception'ın asıl amacı olan "güvenli hata yönetimini zorunlu kılma" fikrini tam tersine çevirir ve hatanın fark edilmeden kaybolmasına yol açar.

Sağlıklı bir tasarım bu iki ucun ortasında durur: gerçekten telafi edilebilir dış koşullar checked, programlama hataları ve kurtarılamaz durumlar unchecked olarak bırakılır. Bu dengeyi farklı proje örnekleri üzerinden görmek, teoriyi pratiğe dökmenin en hızlı yoludur; bu tür karşılaştırmalı örnekler ve daha fazla Java pratiği için yazılım eğitimi blog yazıları düzenli olarak incelenebilir.

Checked ve Unchecked Exception Karşılaştırma Tablosu

Checked ve unchecked exception arasındaki farkları tek bakışta görmek, günlük kod yazarken doğru sınıfı seçmeyi kolaylaştırır. Aşağıdaki tablo, önceki bölümlerde anlatılan ölçütleri özetleyerek yan yana karşılaştırır.

Kriter Checked Exception Unchecked Exception
Derleyici zorunluluğu Yakalanmalı veya throws ile bildirilmelidir Yakalama veya bildirme zorunluluğu yoktur
Örnek sınıflar IOException, SQLException NullPointerException, IllegalArgumentException
Temsil ettiği durum Telafi edilebilir dış koşul Programlama hatası
Tipik kullanım yeri Dosya, ağ ve veritabanı işlemleri İş mantığı doğrulamaları
Metot imzasına etkisi throws bildirimi gerektirir İmzada bildirim gerektirmez

Bu tablo, bir exception türü seçerken göz önünde bulundurulması gereken beş temel boyutu bir arada gösterir. Özellikle metot imzasına etkisi satırı, API tasarımında checked exception seçiminin çağıran kod üzerinde nasıl bir sorumluluk yarattığını hatırlatır; bu nedenle bir sınıfın checked mi unchecked mi olacağına karar verirken yalnızca hatanın kendisi değil, bu hatayı kullanacak geliştiricilerin deneyimi de değerlendirilmelidir.

Kendi Checked Exception Sınıfını Tanımlama: Çalışan Kod Örneği

Teoriyi koda dökmenin en net yolu, gerçek bir senaryo üzerinden ilerlemektir. Aşağıdaki örnekte bir banka hesabından para çekme işlemi ele alınıyor: bakiye yetersizse bu durum bir checked exception olarak modelleniyor, çünkü çağıran kodun bu durumu görmezden gelmesi kabul edilemez. Derleyici, throws ile işaretlenmiş bu istisnayı ya try-catch ile yakalamaya ya da üst metoda devretmeye zorlar.

class InsufficientBalanceException extends Exception {
    public InsufficientBalanceException(String message) {
        super(message);
    }
    public InsufficientBalanceException(String message, Throwable cause) {
        super(message, cause);
    }
}

class Account {
    private double balance;
    Account(double balance) { this.balance = balance; }

    void withdraw(double amount) throws InsufficientBalanceException {
        if (amount > balance) {
            throw new InsufficientBalanceException(
                "Yetersiz bakiye: talep edilen " + amount);
        }
        balance -= amount;
    }
}

public class Main {
    public static void main(String[] args) {
        Account account = new Account(100.0);
        try {
            account.withdraw(150.0);
        } catch (InsufficientBalanceException e) {
            System.out.println("İşlem reddedildi: " + e.getMessage());
        }
    }
}

Burada dikkat edilmesi gereken üç nokta var. Birincisi, InsufficientBalanceException sınıfı doğrudan Exception'dan türetildiği için otomatik olarak checked statüsündedir; RuntimeException'dan türetilseydi throws ibaresi zorunlu olmazdı. İkincisi, iki constructor'ın da super() çağrısıyla üst sınıfa doğru şekilde devredilmesi gerekir; mesaj-cause ikilisini alan constructor özellikle bir istisnayı başka bir istisnaya sararken (exception chaining) kritik önemdedir. Üçüncüsü, withdraw metodu throws InsufficientBalanceException imzasını taşımadan derlenmez — bu, checked exception'ın derleme zamanında dayattığı sözleşmenin somut kanıtıdır.

Bu tür özel exception sınıflarını tasarlarken constructor override mantığını, exception chaining'i ve katman geçişlerinde hangi bilginin korunması gerektiğini uygulamalı örneklerle pekiştirmek isteyenler için birebir Java dersleri kapsamındaki alıştırmalar, bu konuyu soyut kalmaktan çıkarıp gerçek proje senaryolarına taşıyan bir pratik zemin sunar.

Gerçek Projelerde Exception Tasarımı İçin Pratik Öneriler

Katmanlı bir mimaride (controller-service-repository) her katmanın kendi exception sözlüğü olması, hata yönetimini yönetilebilir kılar. Repository katmanında oluşan düşük seviyeli bir hata (örneğin veritabanı bağlantı sorunu), servis katmanına ham haliyle sızdırılmak yerine genellikle daha anlamlı bir uygulama istisnasına sarmalanıp yeniden fırlatılır. Bu sarmalama sırasında orijinal hatanın cause olarak korunması, hata ayıklama sürecinde kök nedenin kaybolmamasını sağlar.

Sektörde yaygın kabul gören bir pratik, kütüphane veya framework geliştirirken checked exception'a, uygulama iç iş mantığında ise ağırlıklı olarak unchecked exception'a yönelmektir. Bunun nedeni, bir kütüphanenin tüketicisinin hangi hatalarla karşılaşabileceğini API sözleşmesi üzerinden açıkça görmesi gerekirken, uygulama içi mantık hatalarının genellikle her çağrı noktasında tek tek ele alınmasının pratik bir katkı sağlamamasıdır. Spring gibi framework'lerin veri erişim katmanında unchecked exception hiyerarşisini tercih etmesi de bu yaklaşımın sektördeki yansımalarından biridir.

Pratikte akılda tutulması gereken birkaç nokta şöyle sıralanabilir:

  • Her exception sınıfına anlamlı ve aranabilir bir isim verin; CustomException gibi genel isimlerden kaçının.
  • Exception sarmalarken orijinal hatayı cause parametresiyle mutlaka koruyun.
  • Bir metodun throws listesini sadece derleyiciyi susturmak için genişletmeyin; her checked exception gerçek bir karar noktasını temsil etmeli.
  • Loglama ve kullanıcıya gösterilecek mesajı birbirinden ayırın; teknik detay log'da kalmalı, kullanıcı mesajı sade olmalı.

Bu tür kararların içselleştirilmesi ancak bolca kod yazıp farklı hata senaryolarını bizzat tetikleyerek mümkündür; bir istisnanın ne zaman yakalanacağını, ne zaman yeniden fırlatılacağını kitap okuyarak değil, kırık bir akışı elle onararak öğrenirsiniz. canlı yazılım eğitimi programlarında bu tür senaryoların canlı ortamda birlikte çözülmesi, öğrencinin exception tasarımını soyut bir kural listesi olarak değil, günlük geliştirme alışkanlığı olarak edinmesine katkı sağlar.

Sık Sorulan Sorular

Checked exception ile unchecked exception arasındaki temel fark nedir?

Checked exception'lar derleme zamanında throws ile bildirilmesi veya try-catch ile yakalanması zorunlu olan, genellikle programcının kontrolü dışındaki dış koşullardan (dosya, ağ, veritabanı) kaynaklanan durumlardır. Unchecked exception'lar ise RuntimeException alt sınıflarıdır, derleyici tarafından zorunlu tutulmaz ve çoğunlukla programlama hatasını işaret eder.

Kendi exception sınıfımı checked mi unchecked mi yapmalıyım?

Çağıran kodun bu durumu görüp bilinçli bir kurtarma stratejisi uygulaması bekleniyorsa checked, hata bir programlama kusurunu veya kurtarılması anlamsız bir durumu işaret ediyorsa unchecked tercih edilmesi sektörde yaygın kabul gören ölçüttür.

RuntimeException'dan türetilen bir exception neden throws ile bildirilmek zorunda değildir?

Java derleyicisi, RuntimeException ve alt sınıflarını "programcı hatası" kategorisinde değerlendirir ve bu tür hataların her metot imzasında ayrı ayrı bildirilmesini zorunlu kılmaz; aksi halde neredeyse her metodun imzası anlamsız derecede uzayabilirdi.

Error sınıfı neden Exception'dan ayrı tutulur, programcı Error'ı yakalamalı mı?

Error sınıfı, uygulamanın normal akışıyla kurtarılamayacak ciddi sistem seviyesi sorunları (bellek yetersizliği gibi) temsil eder ve Exception'dan ayrı bir dalda konumlandırılır. Genel pratikte Error'ın yakalanıp normal akışa devam edilmeye çalışılması önerilmez.

Her exception'ı unchecked yapmak neden kötü bir pratik sayılır?

Tüm hataları unchecked yapmak, API'yi kullanan geliştiricinin hangi hata durumlarıyla karşılaşabileceğini metot imzasından görmesini engeller ve kritik hataların fark edilmeden çalışma zamanına kadar sızmasına yol açabilir.

Checked exception kullanmak API tasarımını nasıl etkiler?

Checked exception, bir metodun sözleşmesinin parçası haline gelir; metodu çağıran her geliştirici olası hata durumunu görmek ve ele almak zorunda kalır. Bu şeffaflık avantaj olsa da, aşırı kullanıldığında imzaları kalabalıklaştırıp kodun okunabilirliğini düşürebilir.

Java'da özel exception sınıfı tanımlarken hangi constructor'lar override edilmelidir?

En az mesaj alan constructor ile mesaj ve cause (kök neden) alan constructor'ın tanımlanması, hem hatanın açıklayıcı bir mesajla taşınmasını hem de exception chaining ile orijinal hatanın izinin korunmasını sağladığı için standart pratik kabul edilir.

Checked ve unchecked exception ayrımı, ezberlenecek bir kural değil, her hata durumunda "bu durumu çağıran kod görmeli mi, görebilir mi" sorusuna verilecek bilinçli bir cevaptır. Bu kararı isabetli verebilmek, uygulamalı pratikle ve gerçek hata senaryolarıyla zaman içinde netleşir; bu süreci desteklemek isteyenler ücretsiz kodlama bilgisi testi ile mevcut seviyelerini ölçerek başlangıç noktalarını belirleyebilir.

Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 300'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara