Gotowi na dalsze wyjaśnienia związane z tym samym artykułem? Został jeszcze jeden element. Pamiętacie dopisek "throws" w nagłówku funkcji? Jest to nieco rzadziej omawiany element a szkoda, bo równie przydatny co samo przechwytywanie wyjątków. Obsługa wyjątków w języku Java to jedno, a "przerzucenie" tej odpowiedzialności na metodę wywołującą to zupełnie inna bajeczka.

OBSŁUGA WYJĄTKÓW RAZEM Z "THROWS"

Nowe słowo kluczowe do Waszego arsenału, tym razem to "throws". Jak zdążyłem już napisać jest ono umieszczane w nagłówku funkcji po zdefiniowaniu ewentualnych parametrów formalnych. Przypomnę dla porządku:

void doSomething([parametry formalne]) throws [wyjątki, które mogą zgłosić "ryzykowne" metody]
{
	// instrukcje wraz z metodami mogącymi zgłosić wyjątek
}

Chcę zaznaczyć, że "throws" a "throw" to są dwa odmienne słowa kluczowe (tym drugim zajmiemy się w osobnym artykule)! Obsługa wyjątków wymaga, aby po zawarciu słowa "throws" podać nazwę wyjątku, który może zostać zgłoszony przez metodę określaną jako "ryzykowna". Ryzykowna to taka, która wykonuje operacje mogące się nie powieść. Musicie jeszcze wiedzieć, że bezzasadne użycie słowa "throws" spowoduje błąd kompilacji. Nie potraktuje tego jako bezużyteczność, tylko jak błąd składniowy.

OK, tylko skąd macie wiedzieć jakie nazwy podać tych wyjątków? Żeby nie tracić czasu na pierdoły, sugerowałbym użycie IDE, które automatycznie podpowie co i jak należy wstawić, a jeśli nie wchodzi to w grę, to tylko dokumentacja. Jeśli nie chcecie się bawić w różnego rodzaju wyodrębnianie jednych przypadków od drugich, to możecie również wstawić samo "Exception". Być może powinienem to napisać na samym początku, ale wyjątki to także obiekty w Javie!

A tak na marginesie, zastosowanie tego słowa pozwala na "przeniesienie" klauzuli "try-catch" do metody wywołującej. Obsługa wyjątków pozwala na taki manewr. Kłopot w tym, że nie wszyscy o nim wiedzą...

PRZYKŁAD PROGRAMU Z UŻYCIEM "THROWS"

Aby już nie utrudniać przedstawię teraz program z absurdalnym działaniem w postaci dzielenia przez zero w celu sprowokowania wyjątku, który tutaj akurat nosi nazwę "ArithmeticException". Obsługa wyjątków też może zaskakiwać o czym przekonacie się za chwilę:

  • KLASA "Main"
public class Main
{
	public static void main(String[] args)
	{
		new IllegalOperation();
	}
}
  • KLASA "IllegalOperation"
public class IllegalOperation
{
	public IllegalOperation()
	{
		try
		{
			divideByZero();
		}
		catch (ArithmeticException e)
		{
			System.out.println("Nie wolno dzielić przez zero!");
		}
	}

	private void divideByZero() throws ArithmeticException
	{
		int x = 12 / 0;
	}
}

Zanim się pożegnamy, mam dla Was jedną ciekawostkę. Możecie uwierzyć lub nie, ale ten kod da się skompilować nawet bez użycia klauzuli "try-catch". Jakim cudem? Takim, że "ArithmeticException" jest jednym z wyjątkowych wyjątków (nie ma to jak masło maślane), które należą do typu "RuntimeException" (wyjątek podczas działania programu). Oznacza to, że kompilator nie wymaga od nas przewidywania zgłoszenia wyjątku jeżeli dotyczy on typu "RuntimeException", gdyż nie ma pewności, że może wystąpić jakieś niebezpieczeństwo. Widzicie jak bardzo sama obsługa wyjątków może być zagmatwana?


Dziękuję po raz trzeci dzisiaj za uwagę. Jest wysoce prawdopodobne, że jeszcze dzisiaj wcisnę czwarty artykuł z rzędu przekraczając granice swoich możliwości.