Po co umieszczać try and catch, lub throws

0

Witam, chciałbym się upewnić, czy dobrze myślę. Mianowicie chodzi mi o wyjątki w Javie. Zaleta użycia tych sposób polega na tym, że gdy nie użyjemy try and catch, czy throws, to i tak dajmy na to w przykładzie zamieszczonym poniżej zostanie wywołany wyjątek NumberFormatException. Oczywiście tworzenie przez nas, czy to try and catch, czy throws pozwala na własnoręcznie zdefiniowanie wyskakującego komunikatu o błędzie. Oprócz tego throws używa się, ponieważ możemy sprawdzić, w której metodzie wystąpił błąd. Try and catch ponadto pozwala jeszcze bardziej szczegółowo określić miejsce błędu, bo może być użyte w danym fragmencie metody itp. Czy dobrze postrzegam ten temat?

public class Test
{

	private static void throwsMethod() throws NumberFormatException
	{
		String intNumber = "5A";

		Integer.parseInt(intNumber);
	}

	private static void catchMethod()
	{
		try
		{

			throwsMethod();

		}
		catch (NumberFormatException e)
		{
			System.out.println("Convertion Error");
		}

	}

	public static void main(String[] args)
	{
		// TODO Auto-generated method stub

		catchMethod();
	}

}
1

Wyjątki słuzą do obsługi sytuacji wyjątkowych. Kiedy coś sie "wysypie" to rzucamy wyjątek który jest gdzieś wyżej obsługiwany. Pozwala to na obsługe błędów w aplikacji.
Kiedyś w C zamiast tego każda funkcja zwracała np. errorcode, ale co zrobić kiedy funkcja zwraca jakąś strukturę albo złożony obiekt? Co zrobić jeśli obsługę błędu chcemy zrobić gdzieś znacznie wyżej? Musiałbyś wtedy opakować cały kod ifami.

Wyobraź sobie że masz kilka poziomów w tym kodzie, number format ex może polecieć gdzieś na samym dole, a wyjątek chcesz obsłużyć na samej górze. Spróbuj to zrobić bez użycia wyjątku ;)

0

No ok, a na czym polega różnica między try and catch, a throws?

0

Nie rozumiem pytania. Blok try...catch pozwala na wykonanie kawałka kodu który może rzucić wyjątek (kod w bloku try) oraz na obsłużenie tego wyjątku (blok catch). Deklaracja throws mówi że dana metoda może rzucić wyjątek.
Wyjątki "checked" (czyli nie RuntimeException) muszą albo zostać obsłużone albo rzucone wyżej. Więc jeśli masz kod który może rzucic wyjątek to albo musisz ten kod opakować w try..catch i obsłużyć ten wyjatek na tym poziomie, albo musisz zadeklarować że twoja metoda może taki wyjątek rzucić.

Chodzi tutaj o to GDZIE obsłuzenie wyjątku ma sens. Jeśli masz jakąś skomplikowaną operacje i jakiś jej element sie "wysypie" to często chciałbyś przerwać operacje i obsłużyć ten problem "na górze" tzn tam gdzie operacja została zainicjowana, a nie na poziomie na którym wystąpił błąd.

0

Zastanawia mnie po co używać tych bloków, skoro i tak domyślnie podczas napotkania na dany błąd pojawi się on u nas w konsoli. Oczywiście poza tym, że możemy wtedy dodać własny opis błędu.

1

@Parasdf ty chyba nie mówisz poważnie. A co jeśli aplikacja działa na serwerze a user komunikuje się z nią przez jakiś webowy interfejs? Albo aplikacja jest okienkowa? Albo user w ogóle nie jest zainteresowany widzeniem stacktrace nigdzie? o_O To programista ma zająć sie obsługą błędów a wypisanie stacktrace nie jest żadnym sensownym obsłużeniem wyjątku i w zasadzie służy tylko do debugowania aplikacji.

Wyobraź sobie że robisz przelew bankowy ale coś sie gdzieś popsuło. Czy wolałbyś żeby w takiej sytuacji serwer odkręcił wszystkie powiązane operacje (np. wycofał pobranie środków z twojego konta) i poinformował cię że wystąpił błąd z takiego czy innego powodu, czy żeby gdzieś na stronie ci się wyświetlił stacktrace z jakimś enigmatycznym wyjątkiem? :D :D

Poza tym nie obsluzenie wyjątku powoduje że leci on w górę PRZERYWAJĄC WYKONANIE PROGRAMU więc jak go nigdzie nie złapiesz to program się po prostu zakończy z błędem. User źle wpisał liczby do przelewu i tym samym wywalił nagle cały system obsługi transakcji w banku :D Mam nadzieje że nigdy nie trafię do tej samej firmy co ty :D

0

Za dobrą praktykę w Javie większość uznaje nieużywanie checked exceptions (throws) jeśli nie ma takiej potrzeby. Większość języków ich nie ma, Java to wyjątek.

0

Catch służy także do dodania informacji kontekstowej do wyjątku i zgłoszenia go dalej.
To gdzie wystąpił wyjątek w Javie wiemy dość dobrze bez żadnej obsługi, ale często brakuje informacji dlaczego taki wyjątek wystąpił.
Wtedy, dodając informację np. o parametrach wejściowych lub stanie obiektu, możemy mieć ułatwioną naprawę błędu (o ile trzeba będzie go naprawiać w ogóle).

0

Polecam try... catch... na mainie.

upraszcza kod.

0

@up Świetny pomysł, rzucajmy wyjątkiem przez cały projekt i łapmy w jednym miejscu. W końcu funkcje na kilkaset linijek znacznie upraszczają kod :D :D Już nie mówiąć o przeciekającej abstrakcji, a raczej jej braku.

0

Wujo dobra rada poleca sie na przyszlosc :p

0
Parasdf napisał(a):

Zastanawia mnie po co używać tych bloków, skoro i tak domyślnie podczas napotkania na dany błąd pojawi się on u nas w konsoli. Oczywiście poza tym, że możemy wtedy dodać własny opis błędu.

Na pewno to nie służy tylko i wyłącznie do tego.
Najbardziej dziecinny przykład jaki przychodzi mi do głowy?
Aplikacja konsolowa, statki. User nie wklepał numeru od 1 do 9 (załóżmy, że numery to miejsca na planszy) tylko wciepał nie wiadomo ile cyfr. Normalnie program wywalił by błąd i się wyłączył. Try ... catch pozwala Ci obsłużyć ten wyjątek, znaleźć receptę na każdą sytuację, której w danym programie chcesz uniknąć (np. poprosić o input jeszcze raz). Nie istnieje program idealny - a TY jako programista jesteś tu po to, żeby user nie wpadł na minę i nie wysypał działania programu. Prawa Murphiego mówią, że:

  1. Jeżeli coś może się nie udać – nie uda się na pewno.
  2. Nie uda się nawet wtedy, gdy jednak nie powinno się nie udać.
  3. Wszystko wali się naraz.

Łapanie wyjątków to naprawdę przydatna rzecz. Polecam poszukać sobie dobrej literatury i zapoznać się z tym bliżej - będziesz z tego korzystał częściej niż myślisz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1