Metoda 1:
This post by Alexey Ragozin opisuje jak korzystać trick rodzajowych aby rzucić nierejestrowanej sprawdzony wyjątek. Od tego postu:
public class AnyThrow {
public static void throwUnchecked(Throwable e) {
AnyThrow.<RuntimeException>throwAny(e);
}
@SuppressWarnings("unchecked")
private static <E extends Throwable> void throwAny(Throwable e) throws E {
throw (E)e;
}
}
Sztuczka polega na throwUnchecked
„leżący” do kompilatora, że typ E
jest RuntimeException
z jego wywołaniu throwAny
. Ponieważ throwAny
jest zadeklarowany jako throws E
, kompilator myśli, że konkretne połączenie może po prostu rzucić RuntimeException
. Oczywiście sztuczka jest możliwa dzięki throwAny
arbitralnie deklarując E
i ślepo na nią rzucając, pozwalając dzwoniącemu zdecydować, do czego argument jest rzucony - straszny projekt podczas kodowania sanely. W czasie wykonywania, E
jest erased i nie ma znaczenia.
Jak już zauważyłeś, robienie czegoś takiego to ogromny hack i powinieneś bardzo dobrze udokumentować jego użycie.
Metoda 2:
Można również użyć sun.misc.Unsafe
do tego celu. Najpierw należy wdrożyć metodę, która wykorzystuje odbicia powrócić instancję tej klasy to:
private static Unsafe getUnsafe() {
try {
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
return (Unsafe)theUnsafeField.get(null);
}
catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Jest to konieczne, ponieważ wywołanie Unsafe.getUnsafe()
zazwyczaj rzucać SecurityException
. Gdy masz wystąpienie Unsafe
można umieścić jej przerażające możliwości użycia:
Unsafe unsafe = getUnsafe();
unsafe.throwException(new Exception());
zasługa this answer na stanowisku https://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe.Pomyślałem, że wspomnę o tym dla kompletności, ale prawdopodobnie lepiej po prostu użyć powyższej sztuczki, zamiast pozwolić na wpisanie Unsafe
do kodu.
Metoda 3:
w komentarzach połączonego odpowiedź na temat korzystania Unsafe
, @bestsss points out znacznie prostszy sztuczka przy użyciu przestarzałej metody Thread.stop(Throwable)
:
Thread.currentThread().stop(new Exception());
W tym przypadku byś użyj @SuppressWarnings("deprecation")
i jeszcze raz dokumentuj bardzo gwałtownie. Znowu wolę pierwszą sztuczkę dla jej (względnej) czystości.
Testujemy, że coś jest niemożliwe stało. Czemu? – rodrigoap
Próbowałem sfałszować odpowiedzi mydła przy użyciu LogicalHandler. W handleMessage (kontekście LogicalMessageContext) nie zadeklarowano wyjątków rzutów. Ale wszystkie wyjątki wyrzucane przez punkt końcowy mydła są podklasą wyjątków. Muszę rzucić ten wyjątek, aby sfałszować moją odpowiedź na usługi. –
Zobacz moją edycję, jeśli jesteś zainteresowany. –