2012-02-21 12 views
21

Jestem programistą C# wykonującym okazyjne kodowanie w Javie. Czy ktoś może wyjaśnić w prosty sposób, jakie są wyjątki sprawdzone w Javie i dlaczego jest potrzebny? Nie natknąłem się na to określenie w języku C#.Co to są sprawdzane wyjątki w języku Java/C#?

+1

Czy chodziło Ci o "sprawdzone wyjątki"? Jeśli tak, edytuj pytanie. – dasblinkenlight

+1

@ dasblinkenlight, został oznaczony jako wyjątek, więc go edytowałem. –

+0

dzięki! przepraszam za tę literówkę. – blitzkriegz

Odpowiedz

43

Wyjątki sprawdzane to wyjątki, których kompilator wymaga w pewien sposób obsługi.

W języku Java sprawdzane wyjątki to Throwable s, które nie są RuntimeException, Error lub jedną z ich podklas.

Projektanci języka Java uważali, że są oni potrzebni do zapewnienia obsługi obsługiwanych wyjątków, które były dość prawdopodobne. Klasycznym przykładem jest IOException. Za każdym razem, gdy program wykonuje I/O, istnieje możliwość awarii. Dysk może być pełny, plik może nie istnieć, może występować problem z uprawnieniami itp.

W ten sposób Java jest zaprojektowana w taki sposób, że program musi w pewien sposób obsługiwać wyjątek pod względem składniowym. Może to być blok catch lub w inny sposób ponownie zgłaszany wyjątek.

C# nie ma sprawdzonych wyjątków. Postanowili pozostawić tę kwestię twórcom aplikacji (interview). Sprawdzane wyjątki są kontrowersyjne, ponieważ mogą sprawić, że kod będzie pełny, a programiści czasami zajmują się nimi z pustymi blokami catch. Ponadto może być dowolne, które metody biblioteki standardowej wyrzucają sprawdzane wyjątki. Na przykład, dlaczego File.delete (nowy interfejs API Java 7 nie robi tego inaczej) rzuca IOException?

Kolejnym problemem, który Hejlsberg zauważył w tym wywiadzie, jest możliwość wersjonowania. Dodanie sprawdzonego wyjątku do klauzuli throw wymusza cały kod, używając tej metody do modyfikacji i ponownej kompilacji.

+1

niesamowite wyjaśnienie. dzięki! – blitzkriegz

+4

'Dodanie sprawdzonego wyjątku do klauzuli throw wymusza cały kod przy użyciu tej metody, która ma zostać zmodyfikowana i zrekompilowana" - tak więc masz niezaznaczone wyjątki. Cóż, z wyjątkiem sytuacji, w których "nie powiodą się w pewnych okolicznościach", możesz opisać swój interfejs API. KAŻDY wyjątek jest częścią publicznego interfejsu metody, a dodanie ich później jest jak powiedzenie "Och, od teraz ten parametr int będzie miał zupełnie inne znaczenie semantyczne - ale nie martw się, jest nadal kompatybilny z binarami!" – Voo

+2

@Voo, jest to omówione szczegółowo w [tej części] (http://www.artima.com/intv/handcuffs2.html) wywiadu. Hejlsberg twierdzi, że nie każdy wyjątek musi być obsługiwany przez natychmiastowy kod wywołujący. Mówi, że niektóre są najlepiej obsługiwane przez główny program obsługi komunikatów, nawet jeśli ten główny program obsługi nie został napisany ze szczególną wiedzą o nowym wyjątku. –

0

Wyjątki sprawdzane to wyjątki wymagające, aby każda klasa "zużywająca" miała kod, który jawnie sprawdza (i mimowolnie obsługuje) wyjątek.

Na przykład, jeśli klasa Apple ma metodę Eat(), która obejmuje sprawdzony wyjątek WormFound, wówczas każdy kod, który wywołuje tę metodę, będzie musiał jawnie mieć przechwycenie dla tego wyjątku.

Na marginesie, jest to funkcja Java, a nie C#.

(W momencie, C# został stworzony, plusy przetestowanych wyjątkami nie były tak oczywiste w oczach zespołu C# więc nie zostały one uwzględnione.)

6

W języku Java sprawdzone wyjątku (jak słusznie zauważa Matthew Flaschen) jest wyjątkiem, którego kompilator wymaga od ciebie. Są wyjątki, które zostały zadeklarowane definicji funkcji (np function bob() throws ImNotBobException { ... } powiedzieć, że wywołanie tej funkcji może rzucić ten wyjątek - np. NumberFormatException podczas analizowania liczbę całkowitą lub IOException podczas pisania do pliku

jednak pewne wyjątki mogą być wyrzucane z nieznane lub nieoczekiwane miejsca, które są po prostu niepraktyczne w obsłudze na każdym poziomie, więc kompilator nie wymaga ich obsługi. Są to niezerowe wyjątki niezaznaczone wyjątki. Mogą być one wyrzucane z różnych miejsc, które nie deklarują ich wyrzucenia (często przez próbę wywołanie metody na obiekcie, gdy ten obiekt nie został jeszcze zainicjowany, tj. ma wartość null - spowoduje to uzyskanie NullPointerException.)

Mam nadzieję, że to pomoże.

+0

sprawdzony wyjątek jest błędem. Każde inne wytłumaczenie jest błędne. – earizon

-2

(kilka lat później, dla osób przybywających tu przez linie Google)

odprawy wyjątków był błąd w konstrukcji języka Java. KROPKA. Za każdym razem, gdy znajdziesz sprawdzony wyjątek, zapakuj je w niezaznaczony wyjątek (prawdopodobnie wyjątek RuntimeException).

Niestety, z powodu problemów marketingowych, pierwszego Słońca, a następnie Oracle nie były w stanie otwarcie rozpoznać ich błąd.

W czasie tworzenia języka Java obsługa wyjątków nie była jasna. Projektanci Java naiwnie myśleli, że zmuszanie programistów do sprawdzania wyjątków podczas kompilacji było dobrym pomysłem. Choć wygląda to intuicyjnie poprawne, okazało się, że jest to anty-wzór, podobny do użycia "GOTO". To nigdy nie działało w praktyce i powodowało wiele problemów. Wyjątki muszą być obsługiwane w "pętli głównej" lub "kontrolerze", ponieważ w przeciwnym razie, gdyby mogły być obsługiwane wewnątrz funkcji powodującej błąd, nie byłyby wyjątkiem, ale rozważanym błędem, który musi być obsługiwany przez normalna wartość zwracana przez API. Wyjątek, ze swej natury, jest czymś, co nie jest rozważane i nie pozwala na normalne wykonywanie kodu.

Należy zauważyć na przykład, że Spring, "standardowe" środowisko Java do tworzenia aplikacji dla przedsiębiorstw, ogranicza się tylko do zawijania sprawdzonych wyjątków do niezaznaczonych wyjątków.

C# rozwiązało ten problem. W rzeczywistości C# nie ma tego problemu.