Poprawne wykorzystanie wyjątków

0

W poradniku dobrego programowania w Javie ("Efektowne programowanie w języku Java") przeczytałem, że wyjątków należy używać tylko do sygnalizacji sytuacji wyjątkowych i nie należy ich wykorzystywać do osiągnięcia innych efektów, gdyż ich implementacja nie jest szczególnie zoptymalizowana (z założenia mają pojawiać się rzadko albo wcale). Piszę coś w rodzaju edytora sprawdzającego wyrażenia pewnego języka programowania. W programie tym występują skomplikowane funkcje analizujące i sprawdzające poprawność łańcuchów znaków. Funkcje te uporządkowane są w sposób hierarchiczny - niższego stopnia szczegółowości wywołują niższego stopnia szczegółowości, niektóre wywołują siebie same rekurencyjnie. I tak się składa, że najlepszym sposobem wykrycia błędu w wyrażeniu wprowadzonym przez użytkownika jest zasygnalizowanie przez funkcję, która wykryła błąd, wyjątku przechowującego informację, co jest nie tak. W momencie wyrzucenia wyjątku, dalsza analiza wprowadzonego kodu jest przerywana, wyjątek jest przekazywany wywołaniom wyższego poziomu, aż dociera do wywołania najwyższego poziomu i użytkownik otrzymuje informacje o popełnionym błędzie. Wszystko to przebiega sprawnie i wygląda dosyć przejrzyście. Mógłbym zmienić program tak, żeby funkcja, która wykryje błąd zwracała specjalną wartość, symbolizującą wystąpienie błędu, a funkcje ją wywołujące "przepychały" tą wartość w górę stosu wywołań, ale byłby to bardzo niezgrabne i być może problematyczne. Tak więc w podobnych przypadkach wykorzystanie wyjątków wydaje się najlepszym rozwiązaniem, ale kłóci się z właściwym ich przeznaczeniem i nie należy do dobrego stylu programowania. Czy znacie jakieś alternatywy? Czy istnieje w Javie jakiś "system przerwań",który zwracałby sterowanie do wywołania najwyższego poziomu, podobny do mechanizmu wyjątków, ale do wykorzystania w zwyczajnych sytuacjach?

0

Zaistnienie błędu parsowania można nazwać sytuacją wyjątkową. Tak działają wszystkie znane mi parsery. Jak nie potrafią czegoś sparsować, to rzucają wyjątek.
Zwracanie specjalnej wartości to pomysł z epoki C.
Nie martw się też o wydajność. Przecież ten wyjątek zostanie rzucony co najwyżej raz w czasie parsowania.

0

Zaistnienie błędu parsowania można nazwać sytuacją wyjątkową. Tak działają wszystkie znane mi parsery. Jak nie potrafią czegoś sparsować, to rzucają wyjątek.

Dobrze to słyszeć.

Nie martw się też o wydajność. Przecież ten wyjątek zostanie rzucony co najwyżej raz w czasie parsowania.

W zasadzie, to masz rację :).

Przyszło mi do głowy, że alternatywnie mógłbym wywoływać sprawdzanie kodu w osobnym wątku i po napotkaniu błędu przerywać ten wątek - wówczas nie musiałbym wykorzystywać wyjątków niezgodnie z ich przeznaczeniem, a osiągnąłbym podobny efekt. Ale chyba rzeczywiście nie ma sensu komplikować sprawy.

0

Caly mechanizm wyjatkow 'kontrolowanych' (checked exceptions) w Javie powstal z zamyslem zastosowania w takich wlasnie sytuacjach - gdy w aplikacji / bibliotece wystapi blad, z ktorym moze ona / klient bibliteki w jakis sposob sobie poradzic bez awaryjnego przerwania dzialania. Tak wiec zastosowany przez Ciebie mechanizm jest jak najbardziej zgodny z filozofia tworcow Javy (o ile uzywasz wyjatkow 'kontrolowanych', tj. dziedziczacych po java.lang.Exception i deklarujesz je klauzula 'throws' w sygnaturze metody). Inna sprawa, ze filozofia ta jest poddawana przez wielu znaczacej krytyce i wywoluje ostre spory w spolecznosci deweloperow Javy...
Warto rzucic okiem na: http://java.sun.com/docs/books/tutorial/essential/exceptions/ (w szczegolnosci 'Unchecked Exceptions — The Controversy')

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