Mam następującą sytuację.
Mam klasę Java, która dziedziczy z innej klasy bazowej i przesłania metodę. Metoda podstawowa nie zgłasza wyjątków i dlatego nie ma throws ...
deklaracji.
Teraz moja własna metoda powinna być w stanie zgłosić wyjątek, ale ja albo mam wybór
- Połknij wyjątek
- Dodaj deklarację rzutów
Oba nie są satysfakcjonujące, ponieważ pierwsza z nich po cichu zignorowałby wyjątek (ok, mógłbym wykonać trochę logowania), a druga wygenerowałaby błędy kompilatora z powodu różnych nagłówków metod.
public class ChildClass extends BaseClass {
@Override
public void SomeMethod() {
throw new Exception("Something went wrong");
}
}
źródło
Oto sztuczka:
class Utils { @SuppressWarnings("unchecked") private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T { throw (T) exception; } public static void throwException(Throwable exception) { Utils.<RuntimeException>throwException(exception, null); } } public class Test { public static void main(String[] args) { Utils.throwException(new Exception("This is an exception!")); } }
źródło
throws
deklaracji.Trzecią opcją jest rezygnacja ze sprawdzania wyjątków (tak jak czasami musi to robić samo standardowe API) i zawinięcie zaznaczonego wyjątku w
RuntimeException
:throw new RuntimeException(originalException);
Możesz użyć bardziej szczegółowej podklasy
RuntimeException
.źródło
Chcę tylko dodać alternatywną odpowiedź, czysto do Twojej wiadomości :
Tak, istnieje sposób na
throws
zgłoszenie sprawdzonego wyjątku bez dodawania deklaracji przy użyciusun.misc.Unsafe
klasy. Jest to opisane w następującym wpisie na blogu:Zgłoś sprawdzony wyjątek z metody bez deklarowania go
Przykładowy kod:
public void someMethod() { //throw a checked exception without adding a "throws" getUnsafe().throwException(new IOException()); } private Unsafe getUnsafe() { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); return (Unsafe) field.get(null); } catch (Exception e) { throw new RuntimeException(e); } }
Jednak nie jest to zalecane. Lepiej jest zawrzeć niezaznaczony wyjątek, jak opisano w niektórych innych odpowiedziach.
źródło
Unsafe
.Dlaczego nie wyrzucisz niezaznaczonego wyjątku? Nie trzeba tego deklarować.
Istnieją dwie możliwości
final
a kompilator wie, które sprawdzone wyjątki zostały przechwycone.To później jest bardziej przydatne, gdy rzucasz wyjątek check w swoim kodzie i przechwytujesz go w kodzie wywołującym, ale warstwy pomiędzy nimi nie wiedzą nic o wyjątku.
źródło
Tak, jest powód, ale w ogóle nie jest to zalecane, możesz użyć:
getUnsafe().throwException(new IOException());
Ta metoda zgłasza sprawdzony wyjątek, ale kod nie jest zmuszony do przechwytywania ani ponownego zgłaszania. Podobnie jak wyjątek czasu wykonywania.
źródło
Oto przykład przechwytywania zaznaczonych wyjątków i umieszczania ich w niezaznaczonym wyjątku:
public void someMethod() { try { doEvil(); } catch (IOException e) { throw new RuntimeException(e); } }
źródło
możesz złapać wyjątek za pomocą bloku try-catch w swojej metodzie przesłoniętej. wtedy nie musisz deklarować instrukcji rzucania.
źródło
Możesz użyć dowolnego wyjątku pochodzącego z samego RuntimeException lub RuntimeException
lub
użyj bloku try-block dla kodu wyrzucającego wyjątki i obsłuż go tam
źródło