CodeGym /Blog Java /Random-PL /Wyjątki: zaznaczone, niezaznaczone i niestandardowe
Autor
Volodymyr Portianko
Java Engineer at Playtika

Wyjątki: zaznaczone, niezaznaczone i niestandardowe

Opublikowano w grupie Random-PL
Cześć! Na ostatniej lekcji poznaliśmy wyjątki w języku Java i zobaczyliśmy przykłady jak z nimi pracować. Dzisiaj przyjrzymy się bliżej strukturze wyjątków i nauczymy się pisać własne wyjątki :)

Rodzaje wyjątków

Jak powiedzieliśmy wcześniej, w Javie jest wiele wyjątków, prawie 400! Ale wszystkie są podzielone na grupy, więc dość łatwo je zapamiętać. Oto jak to wygląda: Wyjątki: zaznaczone, niezaznaczone i niestandardowe — 2 Wszystkie wyjątki mają wspólnego przodka w Throwableklasie. Wywodzą się z niego dwie główne grupy: wyjątki ( Exception ) i błędy ( Error ). Błąd — reprezentuje krytyczny błąd czasu wykonywania związany z działaniem wirtualnej maszyny Java. W większości przypadków błąd nie musi być obsługiwany, ponieważ wskazuje na poważne błędy w kodzie. Najbardziej znane z nich to StackOverflowError (występuje to na przykład, gdy metoda wywołuje się w nieskończoność) i OutOfMemoryError(dzieje się tak, gdy nie ma wystarczającej ilości pamięci do tworzenia nowych obiektów). Jak widać, w takich sytuacjach zwykle nie ma absolutnie nic do obsługi w czasie wykonywania: kod jest po prostu niepoprawnie napisany i wymaga przerobienia. Wyjątek — reprezentuje, cóż, wyjątek: wyjątkową, nieplanowaną sytuację, która ma miejsce podczas działania programu. Nie są tak poważne jak Błąd, ale nadal wymagają naszej uwagi. Wszystkie wyjątki są podzielone na 2 typy: zaznaczone i niezaznaczone . Wyjątki: zaznaczone, niezaznaczone i niestandardowe — 3 Wszystkie sprawdzone wyjątki pochodzą z Exceptionklasy. Co to znaczy „sprawdzone”? Wspomnieliśmy o tym w ostatniej lekcji: „Kompilator Javy zna zatem najczęstsze wyjątki i sytuacje, w których mogą się one pojawić”. Na przykład wie, że jeśli kod odczytuje dane z pliku, plik może łatwo nie istnieć. A takich sytuacji (z których może wywnioskować) jest bardzo dużo. W związku z tym kompilator z wyprzedzeniem sprawdza nasz kod pod kątem obecności tych potencjalnych wyjątków. Jeśli je znajdzie, nie skompiluje kodu, dopóki ich nie obsłużymy lub nie wyrzucimy ponownie. Drugi typ wyjątku to „niezaznaczony”. Pochodzą one z RuntimeExceptionklasy. Czym różnią się od sprawdzonych wyjątków? Wydaje się, że istnieje również wiele różnych klas wywodzących się zRuntimeException(które opisują wyjątki czasu wykonywania). Różnica polega na tym, że kompilator nie przewiduje tych błędów. Wygląda na to, że mówi: „Kiedy kod został napisany, nie znalazłem niczego podejrzanego, ale coś poszło nie tak podczas jego działania. Najwyraźniej w kodzie są błędy!” I rzeczywiście, to prawda. Niesprawdzone wyjątki są najczęściej wynikiem błędów programisty. A kompilator oczywiście nie może przewidzieć każdej możliwej złej sytuacji, którą ludzie mogą stworzyć własnymi rękami. :) Dlatego nie sprawdza, czy takie wyjątki są obsługiwane w naszym kodzie. Napotkałeś już kilka niesprawdzonych wyjątków:
  • Wyjątek ArithmeticException występuje podczas dzielenia przez zero
  • Wyjątek ArrayIndexOutOfBoundsException występuje, gdy próbujesz uzyskać dostęp do pozycji poza tablicą.
Oczywiście można sobie wyobrazić, że twórcy Javy mogli wprowadzić obowiązkową obsługę wyjątków, ale w tym przypadku kod byłby zbyt skomplikowany. Czy dla dowolnej operacji dzielenia musiałbyś napisać try-catchblok, aby sprawdzić, czy przypadkowo podzieliłeś przez zero? Za każdym razem, gdy uzyskałeś dostęp do tablicy, musiałbyś napisać blok, try-catchaby sprawdzić, czy twój indeks jest poza zakresem. Wszystko byłoby kodem spaghetti i byłoby zupełnie nieczytelne. Ma sens, że porzucono ten pomysł. W rezultacie niesprawdzone wyjątki nie muszą być obsługiwane w try-catchblokach ani ponownie zgłaszane (chociaż jest to technicznie możliwe, jak w przypadku błędu).

Jak rzucić własny wyjątek

Oczywiście twórcy Javy nie są w stanie przewidzieć każdej wyjątkowej sytuacji, jaka może wystąpić w programach. Na świecie jest zbyt wiele programów i są one zbyt różnorodne. Ale nie ma się czym martwić, ponieważ w razie potrzeby możesz utworzyć własny wyjątek. To bardzo łatwe do zrobienia. Wszystko, co musisz zrobić, to stworzyć własną klasę. Powinieneś być pewien, że jego nazwa kończy się na „Wyjątek”. Kompilator tego nie wymaga, ale inni programiści czytający twój kod od razu zrozumieją, że jest to klasa wyjątków. Ponadto wskaż, że klasa jest dziedziczona z Exceptionklasy (kompilator tego wymaga). Załóżmy na przykład, że mamy Dogklasę. Możemy wyprowadzać psa za pomocąwalk()metoda. Ale zanim to zrobimy, musimy sprawdzić, czy nasz pupil ma na sobie obrożę, smycz i kaganiec. Jeśli brakuje któregokolwiek z tych narzędzi, zgłaszamy własny wyjątek: DogIsNotReadyException . Jego kod wygląda następująco:

public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
Aby wskazać, że klasa jest wyjątkiem, należy napisać „ extended Exception ” po nazwie klasy (oznacza to, że „klasa wywodzi się z klasy Exception”). W konstruktorze po prostu wywołujemy konstruktor klasy z komunikatemException String (jeśli wystąpi wyjątek, pokażemy użytkownikowi komunikat z opisem błędu). Oto jak to wygląda w kodzie naszej klasy:

public class Dog {

   String name;
   boolean isCollarPutOn;
   boolean isLeashPutOn;
   boolean isMuzzlePutOn;


   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

   }

   public void putCollar() {

       System.out.println("The collar is on!");
       this.isCollarPutOn = true;
   }

   public void putLeash() {

       System.out.println("The leash is on!");
       this.isLeashPutOn = true;
   }

   public void putMuzzle() {
       System.out.println("The muzzle is on!");
       this.isMuzzlePutOn = true;
   }

   public void walk() throws DogIsNotReadyException {

   System.out.println("We're getting ready for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hooray, let's go for a walk! " + name + " is very happy!");
   } else {
       throw new DogIsNotReadyException(name + " is not ready for a walk! Check the gear!");
   }
 }

}
Teraz nasza walk()metoda zgłasza DogIsNotReadyException . Odbywa się to za pomocą słowa kluczowego throw. Jak powiedzieliśmy wcześniej, wyjątek jest obiektem. Tak więc, gdy wystąpi wyjątek (piesowi czegoś brakuje) w naszej metodzie, tworzymy nowy DogIsNotReadyExceptionobiekt i rzucamy go za pomocą słowa kluczowego throw. Do deklaracji metody dodajemy „ throws DogIsNotReadyException ”. Innymi słowy, teraz kompilator jest świadomy, że wywołanie walk()metody może doprowadzić do sytuacji wyjątkowej. W związku z tym ten wyjątek musi zostać obsłużony, jeśli wywołamy tę metodę gdzieś w naszym programie. Spróbujmy to zrobić w main()metodzie:

public static void main(String[] args) {
  
   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();// Unhandled exception: DogIsNotReadyException
}
To się nie skompiluje. Wyjątek nie jest obsługiwany! Zawijamy nasz kod w try-catchblok, aby obsłużyć wyjątek:

public static void main(String[] args) {

   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking the gear! Is the collar on? " + dog.isCollarPutOn + "\r\n Is the leash on? "
       + dog.isLeashPutOn + "\r\n Is the muzzle on? " + dog.isMuzzlePutOn);
   }
}
Teraz spójrzmy na dane wyjściowe konsoli: Kołnierz jest włączony! Kaganiec jest włączony! Szykujemy się na spacer! Buddy nie jest gotowy na spacer! Sprawdź bieg! Sprawdzanie przekładni! Czy kołnierz jest założony? true Czy smycz jest założona? false Czy kaganiec jest założony? true Zobacz, o ile więcej informacji zawierało wyjście konsoli! Widzimy każdy krok podjęty w programie; widzimy, gdzie wystąpił błąd, a także od razu możemy dokładnie zobaczyć, czego brakuje naszemu psu. :) I tak tworzy się własne wyjątki. Jak widać, nie ma w tym nic skomplikowanego. I chociaż twórcy Javy nie pofatygowali się, aby w języku umieścić specjalny wyjątek dla słabo wyposażonych psów, naprawiliśmy ich niedopatrzenie. :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION