CodeGym/Blog Java/Random-PL/Wyjątki w Javie
Autor
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Wyjątki w Javie

Opublikowano w grupie Random-PL
Cześć! W dzisiejszej lekcji porozmawiamy o wyjątkach Java. Codzienność pełna jest sytuacji, których nie jesteśmy w stanie przewidzieć. Na przykład wstajesz rano do pracy i szukasz ładowarki do telefonu, ale nigdzie nie możesz jej znaleźć. Idziesz do łazienki pod prysznic i odkrywasz, że rury są zamarznięte. Wsiadasz do samochodu, ale nie chce się uruchomić. Człowiek jest w stanie dość łatwo poradzić sobie z takimi nieprzewidzianymi okolicznościami. W tym artykule postaramy się dowiedzieć, jak radzą sobie z nimi programy Java.

Co to jest wyjątek Java?

W świecie programowania błędy i nieprzewidziane sytuacje w wykonywaniu programu nazywane są wyjątkami. W programie mogą wystąpić wyjątki z powodu nieprawidłowych działań użytkownika, niewystarczającej ilości miejsca na dysku lub utraty połączenia sieciowego z serwerem. Wyjątki mogą również wynikać z błędów programistycznych lub nieprawidłowego użycia API. W przeciwieństwie do ludzi w prawdziwym świecie, program musi dokładnie wiedzieć, jak radzić sobie w takich sytuacjach. W tym celu Java ma mechanizm znany jako obsługa wyjątków.

Kilka słów o słowach kluczowych

Obsługa wyjątków w Javie opiera się na wykorzystaniu w programie następujących słów kluczowych:
  • try - definiuje blok kodu, w którym może wystąpić wyjątek;
  • catch - definiuje blok kodu, w którym obsługiwane są wyjątki;
  • w końcu — definiuje opcjonalny blok kodu, który, jeśli jest obecny, jest wykonywany niezależnie od wyników bloku try.
Te słowa kluczowe służą do tworzenia specjalnych konstrukcji w kodzie: try{}catch , try{}catch{}wreszcie , try{}wreszcie{} .
  • throw - używany do zgłaszania wyjątku;
  • throws — używane w sygnaturze metody do ostrzeżenia, że ​​metoda może zgłosić wyjątek.
Przykład użycia słów kluczowych w programie Java:
// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

Dlaczego potrzebujemy wyjątków?

Spójrzmy na przykład z prawdziwego świata. Wyobraź sobie, że na odcinku autostrady znajduje się mały most o ograniczonej nośności. Jeśli przejedzie po nim samochód cięższy niż limit mostu, może się on zawalić. Sytuacja kierowcy stałaby się, delikatnie mówiąc, wyjątkowa. Aby tego uniknąć, dział transportu instaluje znaki ostrzegawcze na drodze, zanim coś pójdzie nie tak. Widząc znak ostrzegawczy, kierowca porównuje masę swojego pojazdu z maksymalną masą mostu. Jeśli pojazd jest zbyt ciężki, kierowca wybiera trasę objazdową. Wydział transportu po pierwsze umożliwił kierowcom ciężarówek zmianę trasy w razie potrzeby, po drugie ostrzegał kierowców o niebezpieczeństwach na głównej drodze, a po trzecie ostrzegał kierowców, że w pewnych warunkach nie wolno korzystać z mostu. Wyjątki w Javie — 2Możliwość zapobiegania i rozwiązywania wyjątkowych sytuacji w programie, pozwalająca na jego dalsze działanie, jest jednym z powodów używania wyjątków w Javie. Mechanizm wyjątków pozwala również chronić swój kod (API) przed niewłaściwym użyciem poprzez walidację (sprawdzanie) wszelkich danych wejściowych. Teraz wyobraź sobie, że jesteś działem transportu przez sekundę. Po pierwsze, musisz znać miejsca, w których kierowcy mogą spodziewać się kłopotów. Po drugie, musisz stworzyć i zainstalować znaki ostrzegawcze. I wreszcie, musisz zapewnić objazdy, jeśli pojawią się problemy na głównej trasie. W Javie mechanizm wyjątków działa w podobny sposób. Podczas programowania używamy bloku try , aby zbudować „bariery wyjątków” wokół niebezpiecznych sekcji kodu, zapewniamy „trasy zapasowe” za pomocą catch {}bloku i piszemy kod, który powinien działać bez względu na wszystko w bloku ultimate{} . Jeśli nie możemy zapewnić „trasy zapasowej” lub chcemy dać użytkownikowi prawo wyboru, musimy przynajmniej ostrzec go o niebezpieczeństwie. Dlaczego? Wyobraźcie sobie oburzenie kierowcy, który nie widząc ani jednego znaku ostrzegawczego wjeżdża na mały mostek, którego nie może przejechać! W programowaniu, pisząc nasze klasy i metody, nie zawsze jesteśmy w stanie przewidzieć, jak mogą zostać użyte przez innych programistów. W rezultacie nie możemy przewidzieć w 100% poprawnego sposobu rozwiązania wyjątkowej sytuacji. To powiedziawszy, dobrze jest ostrzec innych o możliwości wystąpienia wyjątkowych sytuacji. Mechanizm wyjątków Javy pozwala nam to zrobić za pomocą rzutówsłowo kluczowe — zasadniczo deklaracja, że ​​ogólne zachowanie naszej metody obejmuje zgłaszanie wyjątku. Dlatego każdy, kto korzysta z tej metody, wie, że powinien napisać kod obsługujący wyjątki.

Ostrzeganie innych przed „kłopotami”

Jeśli nie planujesz obsługi wyjątków w swojej metodzie, ale chcesz ostrzec innych, że mogą wystąpić wyjątki, użyj słowa kluczowego throws . To słowo kluczowe w sygnaturze metody oznacza, że ​​w pewnych warunkach metoda może zgłosić wyjątek. To ostrzeżenie jest częścią interfejsu metody i umożliwia użytkownikom implementację własnej logiki obsługi wyjątków. Po rzutach określamy typy zgłaszanych wyjątków. Zwykle wywodzą się one z klasy wyjątków Javy . Ponieważ Java jest językiem zorientowanym obiektowo, wszystkie wyjątki są obiektami w Javie. Wyjątki w Javie — 3

Hierarchia wyjątków

Gdy podczas działania programu wystąpi błąd, JVM tworzy obiekt odpowiedniego typu z hierarchii wyjątków Java — zestawu możliwych wyjątków pochodzących od wspólnego przodka — klasy Throwable . Wyjątkowe sytuacje runtime możemy podzielić na dwie grupy:
  1. Sytuacje, z których program nie może się wycofać i kontynuować normalnej pracy.
  2. Sytuacje, w których możliwe jest wyzdrowienie.
Pierwsza grupa obejmuje sytuacje związane z wyjątkiem pochodzącym z klasy Error . Są to błędy, które występują z powodu awarii JVM, przepełnienia pamięci lub awarii systemu. Zwykle wskazują na poważne problemy, których nie można naprawić za pomocą oprogramowania. W Javie możliwość wystąpienia takich wyjątków nie jest sprawdzana przez kompilator, dlatego są one znane jako niesprawdzone wyjątki. Ta grupa obejmuje również wyjątki RuntimeExceptions, które są wyjątkami pochodzącymi od wyjątkuclass i są generowane przez maszynę JVM w czasie wykonywania. Często są one spowodowane błędami programistycznymi. Te wyjątki nie są również sprawdzane (odznaczane) w czasie kompilacji, więc nie musisz pisać kodu do ich obsługi. Druga grupa obejmuje wyjątkowe sytuacje, które można przewidzieć podczas pisania programu (i dlatego należy napisać kod, który je obsłuży). Takie wyjątki nazywane są wyjątkami sprawdzonymi. Jeśli chodzi o wyjątki, większość pracy programisty Java polega na obsłudze takich sytuacji.

Tworzenie wyjątku

Podczas uruchamiania programu wyjątki są generowane przez maszynę JVM lub ręcznie za pomocą instrukcji throw . Gdy tak się dzieje, w pamięci tworzony jest obiekt wyjątku, główny przepływ programu zostaje przerwany, a program obsługi wyjątków maszyny JVM próbuje obsłużyć wyjątek.

Obsługa wyjątków

W Javie tworzymy bloki kodu, w których przewidujemy potrzebę obsługi wyjątków za pomocą konstrukcji try{}catch , try{}catch{}finally i try{}finally{} . Gdy w bloku tryWyjątki w Javie — 4 zostanie zgłoszony wyjątek , JVM szuka odpowiedniej procedury obsługi wyjątku w następnym bloku catch . Jeśli blok catch ma wymaganą procedurę obsługi wyjątków, sterowanie jest do niego przekazywane. Jeśli nie, JVM szuka dalej w łańcuchu bloków catch , aż do znalezienia odpowiedniego modułu obsługi. Po wykonaniu bloku catch sterowanie jest przekazywane do opcjonalnego bloku ostatecznie . Jeśli odpowiedni połówblok nie zostanie znaleziony, wówczas JVM zatrzymuje program i wyświetla ślad stosu (bieżący stos wywołań metod), po pierwszym wykonaniu bloku ultimate , jeśli istnieje. Przykład obsługi wyjątków:
public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
Oto wyniki głównej metody :
Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
Final jest zwykle używany do zamykania wszelkich strumieni i zwalniania wszelkich zasobów otwartych/przydzielonych w bloku try . Jednak podczas pisania programu nie zawsze jest możliwe śledzenie zamknięcia wszystkich zasobów. Aby ułatwić nam życie, programiści Javy oferują konstrukcję try-with-resources , która automatycznie zamyka wszystkie zasoby otwarte w bloku try . Nasz pierwszy przykład można przepisać za pomocą try-with-resources :
public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
Dzięki możliwościom Javy wprowadzonym w wersji 7 możemy również łączyć wychwytywanie heterogenicznych wyjątków w jeden blok, dzięki czemu kod jest bardziej zwarty i czytelny. Przykład:
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Najważniejsze

Korzystanie z wyjątków w Javie pozwala na zwiększenie niezawodności programów poprzez tworzenie „tras zapasowych”, stosowanie bloków catch w celu oddzielenia kodu głównego od kodu obsługi wyjątków oraz stosowanie rzutów w celu przeniesienia odpowiedzialności za obsługę wyjątków na każdego, kto używa Twojej metody.
Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy