Zagadka Java #8

Zagadki Java zawierają różnego rodzaju niuanse języka i „podchwytliwe” fragmenty kodu. Każda następna zagadka będzie zawierała odpowiedź i wyjaśnienie do poprzedniej. Lista wszystkich zagadek.

Jeżeli znasz odpowiedź, podziel się nią w komentarzu!

Zagadka Java #8

Czy poniższa klasa się skompiluje? Jeżeli tak, to jaki będzie efekt jej uruchomienia?

public class SwitchExpression {
  public static void main(String[] args) {
    if (isWeekend(6)) {
      System.out.println("Weekend!");
    } else {
      System.out.println("Work, work.");
    }
  }

  public static boolean isWeekend(int dayNumber) {
    return
      switch (dayNumber) {
          case 6, 7 -> true;
          default -> false;
      };
  }
}

Odpowiedź do poprzedniej zagadki #7

Poniżej znajdziesz odpowiedź do poprzedniej zagadki.

Klasa CatchThrowable jest poprawna – skompiluje się i wykona bez błędów, a w wyniku jej działania, na ekranie zobaczymy następujące komunikaty:

Wystąpił błąd. Czyżbyś dzielił przez zero? Infinity

Poza wymaganiem wiedzy na temat wyniku dzielenia liczb typów prymitywnych przez zero, ta zagadka miała na celu także sprawdzenie znajomości hierarchii dziedziczenia wyjątków w Javie.

Zazwyczaj, gdy chcemy złapać niezdefiniowany wyjątek, korzystamy z typu Exception, który jest typem bazowym zarówno dla wyjątków Checked, jak i Unchecked, jednak w powyższej zagadce stosujemy typ Throwable w sekcjach catch obu instrukcji try. Dlaczego kod kompiluje się bez błędów?

Klasa Exception nie jest bazową klasą wszystkich wyjątków – to miano posiada klasa Throwable, która jest klasą nadrzędną klas Exception oraz Error. Możemy zatem stosować ją w sekcjach catch instrukcji try.

Dlaczego jednak na ekranie widzimy dwa różne komunikaty, skoro w obu przypadkach wykonujemy dzielenie przez zero?

Dwie przeładowane metody divide, które zdefiniowane są w klasie CatchThrowable, przyjmują, odpowiednio, argumenty typu int oraz double. W języku Java wynik dzielenia przez zero jest zdefiniowane w inny sposób dla tych dwóch typów. W przypadku typu int, próba dzielenia przez zero kończy się rzuceniem wyjątku ArithmeticException, dlatego w wyniku działania poniższego fragmentu kodu:

try {
  System.out.println(divide(5, 0));
} catch (Throwable t) {
  System.out.println("Wystąpił błąd. Czyżbyś dzielił przez zero?");
}

na ekran wypisywany jest komunikat „Wystąpił błąd. Czyżbyś dzielił przez zero?”. Wyjątek ArithmeticException łapany jest i obsługiwany w klauzuli catch.

W przypadku drugiego fragmentu kodu:

try {
  System.out.println(divide(5.0, 0.0));
} catch (Throwable t) {
  System.out.println("Wystąpił błąd. Czyżbyś dzielił przez zero?");
}

wyjątek nie jest rzucany, ponieważ dzielenie przez zero, wykonywane na wartościach typu double, daje w rezultacie specjalną wartość „nieskończoność”, czyli „Infinity”, co widzimy na ekranie po uruchomieniu programu stanowiącego tę zagadkę.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Nie musisz podawać swojego imienia, e-mailu, ani strony www, aby opublikować komentarz. Komentarze muszą zostać zatwierdzone, aby były widoczne na stronie.