Aby nasz system był odporny na błędy programista może napisać własne wyjątki które zostaną przechwycone w bloku try-catch. Ma to zastosowanie gdy w standardowej hierarchii Javy nie ma wyjątku który odpowiadał by potrzebom naszej aplikacji. Tworząc własny wyjątek możemy poinformować użytkownika co poszło nie tak. Warto tutaj pamiętać aby nazwa klasy kończyła się słowem Exception ponieważ wtedy od razu wiadomo do czego służy. Schemat utworzenia wyjątku wygląda następująco:
public class nazwaWyjatkuException extends Exception{} lub wersja z róznymi przeciażeniami konstruktora. public class nazwaWyjatkuException extends Exception{ public nazwaWyjatkuException() {} public nazwaWyjatkuException(String message) {super(message);} public nazwaWyjatkuException(Throwable t){super(t);} }
Zawsze dany wyjątek rozszerza daną grupę wyjątków do którego należy. Teraz przykład który lepiej zobrazuje pokazany powyżej schemat. Ponieważ przykład będzie przedstawiał weryfikacje wieku user’a zacznę do przedstawienia wyjątków. Główny wyjątek UserException dziedziczy po Exception, następnie UserException został sprecyzowany jeszcze o BadAgeException. W tak drobnym przykładzie nie ma potrzeby tworzenia takiej hierarchii – jednak chciałam również to przedstawić.
public class UserException extends Exception{ public UserException(String message){ super(message); } }
W wyjątku zamiast String message można tutaj zdefiniować jakiego typu dany wyjątek dotyczy. W przypadku tego przykładu jest wiek więc Integer. Ponieważ informacja zwrotna jest przekazywana w postaci Stringa wykorzystana została tutaj metoda String.format (). definiując w ten sposób wyjątek tylko w jednym miejscu posługujemy się łańcuchem znaków. Dzięki temu chronimy system przed niechcianymi literówkami.
public class BadAgeException extends UserException { public BadAgeException(Integer age){ super(String.format("Invalid age: %s exception", age)); } }
Klasa user jest klasą modelową w której przechowywane są podstawowe informacje na temat User’a. W klasie UserLogic zostały zaimplementowane dwie metody: przedstawienie wieku oraz statusu user’a. W klasie tej wyjątki zostały wyrzucone z metody i dodane do jej sygnatury:
public class User { String status; Integer age; private String name; //konstruktor, gettery, settery
Deklarując własne wyjątki best practice mówi, żeby robić to rozszerzając RuntimeException – te wyjątki nie wymuszają opakowywania kodu/metod, które je rzucają w try-catch, pozwalają na obsługę wyjątków tam chce chcesz a nie tam gdzie używasz metody. Dlatego w nowszych bibliotekach/frameworkach (np Spring) baaardzo rzadko spotyka się wyjątki typu checked.