U Javi postoje dve vrste izuzetaka, checked i unchecked.
Checked izuzeci proširuju klasu java.lang.Exception i kompajler insistira da
oni budu uhvaćeni ili eksplicitno bačeni.
Unchecked ili Runtime izuzeci proširuju klasu java.lang.RuntimeException
i oni ne moraju biti uhvaćeni.
Java je jedini viši OO jezik koji podržava Checked izuzetke. Svi izuzeci u
C++ ili C# jeziku su ekvivalent Runtime izuzecima u Javi.
Preporuka prema Java tutorijalima je da se uvek koriste Checked izuzeci jer se na taj način može u potpunosti kontrolisati rad sistema. Korišćenje Runtime izuzetaka se smatra programerskom lenjošću da hvata silne izuzetke koje kompajler baca.
Ovakva teza stoji ukoliko su u pitanju manji projekti sa manje koda. Međutim, da li je ovo sasvim ispravna logika kada se radi na velikim projektima sa par hiljada klasa?
Problemi koji se sreću prilikom korišćenja Checked izuzetaka:
Ovi problemi nikako ne treba da sugerišu da se Checked izuzeci potpuno izbace.
Naprotiv, treba da pokažu da je potrebno shvatiti kada koristiti koje izuzetke.
Na primer, ukoliko klijent kupuje neku robu preko debitne kartice a nema dovoljno
novca na računu, bacanje recimo PriceExceedsLimitException ima punog smisla jer je to
nešto na šta sam korisnik može da utiče. Kupiće ono što može sebi da priušti.
Sa druge strane, bacanje greške ConnectionToDatabaseFailedException jer se neki biznis
metod nije mogao konektovati na bazu iz nekog razloga, za krajnjeg korisnika nema
apsolutno nikakvog značaja. On tu ništa ne može da promeni. RuntimeException u ovakvom
slučaju ima smisla koristiti.
Kada se baci RuntimeException, to obično dovodi do suspenzije Thread-a, ali to ne
treba mnogo da nas brine jer kontrola Thread-ova se ionako vrši u J2EE kontejneru.
Kontejner će suspendovati taj Thread (uništiće EJB instancu) i poruku logovati.
Ukoliko je greška fatalna, kao što je recimo nemogućnost konekcije na bazu, EJB instanca
i treba da bude ugašena jer nam ničemu više ne služi. Ne može da obavi traženi posao.
Hint: Da se ne bi izgubio stack trace prilikom umotavanja jednog izuzetka u drugi, od Jave 1.4 je uveden novi konstruktor u Exception klasu koji se koristi kao:
catch (RootCauseException ex) {
throw new MyJavaException("Detailed message", ex);
}Ukoliko se koristi kod koji je pisan u starijoj Java verziji, i dalje se može izbeći gubitak stack trace-a, bacanjem izuzetka na sledeći način:
catch (RootCauseException ex) {
MyException mex = new MyException("Detailed message");
mex.initCause(ex);
throw mex;
}