Kolejna część kursu programowania w Javie! Zanim rozpocznę dodatkową serię, roboczo nazwaną Java By Example, chciałbym omówić jeszcze jeden zdecydowanie ważny element języka jakim są wyjątki (ang. Exceptions). Wyjątki w Javie potrafią zaskoczyć. Powiem szczerze że niektóre decyzje projektowe zaskakują mnie do dziś na tym obszarze 😉

01. Java Exceptions

Wyjątki w Javie standardowo dzielimy na dwie grupy – Checked exceptions oraz Unchecked Exceptions. Różnica polega na tym że Checked exceptions muszą zostać obsłużone przez programistę, natomiast Unchecked Exceotions mogą być „pozostawione” same sobie. Tyle jeśli chodzi o prostą teorię.

Zawsze pomocny przy takich tematach jest mały diagram 😊 zatem proszę bardzo:

Małe wyjaśnienie. Wszystko co dziedziczy po klasie Throwable zaliczamy do wyjątków, mamy początkowe rozgałęzienie na Error oraz Exception.

Error w 99,9% nie powinien nas przejmować, w momencie kiedy nasz program sypnie errorem nie jesteśmy w stanie nic zrobić. Nasz program po prostu „padnie”. Musimy wtedy poszukać błędu w naszej logice może pojawiła się jakaś nieskończona pętla? Może dodajemy bardzo wiele elementów do ArrayListy co spowoduje przepełnienie pamięci? Tak czy siak, jeśli nasz program wyrzuci error, prawdopodobnie się wyłączy.

W drugiej gałęzi mamy klasę Exception, jest to pierwszy z Checked exceptions (pomijając Throwable który jest rodzicem dla wszystkich wyjątków 😉 ) – wyjątek który musi zostać obsłużony przez programistę. Poniżej mamy RuntimeException który jest pierwszym z Unchecked excptions – wyjątków które nie wymagają od programisty żadnych akcji 😊

02. Try - Catch - Finally

Podstawowym mechanizmem jest blok try catch finally, z czego blok finally jest opcjonalny, jest to blok kodu który zawsze się wykona, bez znaczenia czy wystąpi wyjątek czy nie.

try {
    //code
} catch (Exception ex) {
    //code
} finally {
    //code 
}

03. Checked Exceptions

Checked Exceptions – na diagramie są zaznaczone kolorem czerwonym. Nie są to wszystkie wyjątki Checked Exception’y! Nie starczyło by mi nocy żeby wyrysować je wszystkie 😉 Tak jak zostało to wcześniej powiedziona, są to wyjątki które muszą zostać obsłużone przez programistę.

Jednym z najbardziej popularnych tego typu wyjątków to IOException:

String pathToFile = "C:\\Users\\abc.txt";
BufferedReader bufferedReader = null;
try {
    bufferedReader = new BufferedReader(new FileReader(pathToFile));
    System.out.println(bufferedReader.readLine());
} catch (IOException e) {
    e.printStackTrace();
    System.out.println(e.getMessage());
} finally {
    if(bufferedReader != null) {
        try {
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    System.out.println("blok finally wykona sie zawsze :)");
}

Co tu się dzieje? Po prostu próbujemy odczytać plik znajdujący się na dysku naszego komputera. Wiele rzeczy przy takiej operacji może pójść nie tak! Chociażby – nie ma takiego pliku w określonej ścieżce.

W momencie kiedy próbujemy użyć metody która w swojej sygnaturze mówi o tym iż może rzucić takim wyjątkiem, nasze IDE podpowie nam, iż musimy taki wyjątek obsłużyć.

Np. metoda readLine()

public String readLine() throws IOException

Aby użyć takiej metody możemy ją zamknąć w bloku try catch tak jak zostało to przedstawione powyżej, lub przesłać wyjątek „dalej do góry”

public static void main(String[] args) throws IOException {
    String pathToFile = "C:\\Users\\abc.txt";
    BufferedReader bufferedReader = null;
    bufferedReader = new BufferedReader(new FileReader(pathToFile));
    System.out.println(bufferedReader.readLine());
}

04. Unchecked Exceptions

Unchecked Exception – na diagramie oznaczone kolorem zielonym, są to wyjątki które nie wymagają od programisty żadnej reakcji.  Przykład:

String param = "abc";
Integer number = Integer.valueOf(param);

Jednak oczywiście jeśli mamy takie życzenie, możemy obsłużyć taki wyjątek:

String param = "abc";
try {
    Integer number = Integer.valueOf(param);
    System.out.println("Udała się konwersja na liczbę :)");
} catch (NumberFormatException e) {
    System.out.println("Ejjj '"+param+"' to nie jest liczba!");
}

 

Nieprzypadkowo wybrałem tego typu przykład 😉 Na StackOverflow jest bardzo fajny temat w którym ludzie dyskutują na temat czy np. NumberFormatException powinien być typu checked (powinna być wymagana obsługa), no ale polecam zajrzeć już do tego wpisu. Naprawdę bardzo ciekawa lektura!

05. Podsumowanie

Temat wyjątków został jedynie zarysowany w tym wpisie 😊 Jednak jest to solidna podstawa która w połączeniu z resztą kursu pozwoli nam pisać podstawowe aplikacje! Koncepcje wyjątków w Javie jeszcze poruszę w bardziej zaawansowanym stopniu, w późniejszej części kursu!