Uncatchable ChuckNorrisException


596

Czy można zbudować fragment kodu w Javie , który uczyniłby hipotetyczną nie do zdobycia java.lang.ChuckNorrisException?

Przemyślone myśli wykorzystują na przykład przechwytywacze lub programowanie zorientowane na aspekty .



2
stosując sugestię z linku @jschoen warunkiem (wyłączyć kod bajtowy weryfikator), które mogą rzucić coś, co nie rozciąga Throwable! opisane w mojej odpowiedzi poniżej.
jtahlborn,

4
Ten fragment odpowiedzi aioobe dość dobrze podsumowuje pytanie, które @jschoen łączyło całkiem dobrze: „Tj. Twoje pytanie można interpretować jako„ jeśli JVM odbiega od specyfikacji, czy może robić dziwne rzeczy, takie jak rzucanie prymitywami ”, a odpowiedź brzmi oczywiście: tak."
Dan Is Fiddling By Firelight,

2
@Max - Czy możesz opracować praktyczne zastosowania tego?
Vineet Bhatia,

3
co powiesz na wyjątek, który ponownie się powraca finalize()?
Lie Ryan,

Odpowiedzi:


314

Nie próbowałem tego, więc nie wiem, czy JVM ograniczyłby coś takiego, ale być może mógłbyś skompilować kod, który rzuca ChuckNorrisException, ale w czasie wykonywania podaj definicję klasy, ChuckNorrisExceptionktóra nie rozszerza Throwable .

AKTUALIZACJA:

To nie działa Generuje błąd weryfikatora:

Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow.  Program will exit.

AKTUALIZACJA 2:

Właściwie możesz to uruchomić, jeśli wyłączysz weryfikator kodu bajtowego! ( -Xverify:none)

AKTUALIZACJA 3:

Dla tych, którzy przychodzą z domu, oto pełny skrypt:

Utwórz następujące klasy:

public class ChuckNorrisException
    extends RuntimeException // <- Comment out this line on second compilation
{
    public ChuckNorrisException() { }
}

public class TestVillain {
    public static void main(String[] args) {
        try {
            throw new ChuckNorrisException();
        }
        catch(Throwable t) {
            System.out.println("Gotcha!");
        }
        finally {
            System.out.println("The end.");
        }
    }
}

Klasy kompilacji:

javac -cp . TestVillain.java ChuckNorrisException.java

Biegać:

java -cp . TestVillain
Gotcha!
The end.

Skomentuj „przedłuża wyjątek RuntimeException” i rekompiluj ChuckNorrisException.javatylko :

javac -cp . ChuckNorrisException.java

Biegać:

java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain.  Program will exit.

Uruchom bez weryfikacji:

java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"

18
OK, a co jeśli złapiesz Objectzamiast Throwable, to? (Kompilator na to nie zezwala, ale skoro już wyłączyliśmy weryfikator, być może można by zhakować kod bajtowy, aby to zrobić.)
Ilmari Karonen

11
Zgodnie z tym, co możesz rzucać w Javie , nadal możesz łapać rzeczy, które nie rozszerzają możliwości rzucania, ale rzucanie i łapanie ich jest niezdefiniowanym zachowaniem.
VolatileDream

8
@dzieciou Mogą być prawdziwe razem. Możesz być w stanie je złapać za pomocą swojej wersji środowiska Java w konkretnej wersji systemu operacyjnego na typie procesora. Ale jeśli nie jest określone w standardzie, czy MOŻNA go złapać, nazywa się to nieokreślonym zachowaniem, ponieważ inne implementacje Java mogą zdecydować, że nie będzie można go złapać.
heinrich5991

2
Hmmph. Miałem nadzieję, że dla 176 głosów pozytywnych napisałeś kod JNI, który łata cały stos wywołań, aby odrzucić twój wyjątek (oczywiście wywołany przez ctor).
kdgregory

3
Robiąc to wszystko, dobrym pomysłem jest stać na jednej nodze, poklepać się po głowie i pocierać brzuch podczas gwizdania dixie ...;);)
Glen Best

120

Po zastanowieniu się, udało mi się stworzyć wyjątkowy wyjątek. Zdecydowałem się jednak nazwać to JulesWinnfield, a nie Chuck, ponieważ jest to jeden wyjątek od grzybów-chmur-matek-matek. Co więcej, może nie być to dokładnie to, co miałeś na myśli, ale na pewno nie da się go złapać. Przestrzegać:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield()
    {
        System.err.println("Say 'What' again! I dare you! I double dare you!");
        System.exit(25-17); // And you shall know I am the LORD
    }
}


public static void main(String[] args)
{       
    try
    {
        throw new JulesWinnfield();
    } 
    catch(JulesWinnfield jw)
    {
        System.out.println("There's a word for that Jules - a bum");
    }
}

Zrobione! Nieprzechwycony wyjątek.

Wynik:

biegać:

Powiedz co jeszcze raz! Wyzywam cię! Dwukrotnie się odważę!

Wynik Java: 8

BUDOWANIE SUKCESEM (całkowity czas: 0 sekund)

Kiedy będę miał trochę więcej czasu, zobaczę, czy nie mogę wymyślić czegoś innego.

Sprawdź również:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield() throws JulesWinnfield, VincentVega
    {
        throw new VincentVega();
    }
}

public static class VincentVega extends Exception
{
    VincentVega() throws JulesWinnfield, VincentVega
    {
        throw new JulesWinnfield();
    }
}


public static void main(String[] args) throws VincentVega
{

    try
    {
        throw new JulesWinnfield();
    }
    catch(JulesWinnfield jw)
    {

    }
    catch(VincentVega vv)
    {

    }
}

Powoduje przepełnienie stosu - ponownie wyjątki pozostają nieprzechwycone.


32
+1 za użycie przepełnienia stosu w odpowiedzi. Żartowałem, naprawdę dobra odpowiedź.
Josiah

7
Właściwy „niezatapialny wyjątek” zapewniłby, że wszystkie otaczające bloki ostatecznie wykonałyby się bez żadnych pośrednich chwytów. Zabicie systemu nie rzuca wyjątku - po prostu zabija system.
supercat,

4
Jak „rzucasz” JulesWinfield? Czy system nie zatrzyma się z piskiem, zanim zostanie wyrzucony?
supercat

6
@mikeTheLiar: System wychodzi z konstruktora, prawda? Oświadczenie throw new Whatever()to tak naprawdę dwie części: Whatever it = new Whatever(); throw it;i system umiera, zanim dotrze do drugiej części.
supercat

5
@mikeTheLiar naprawdę łatwo złapiesz Julesa lub Vincenta ... jeśli uda ci się go rzucić. Łatwo jest stworzyć wyjątek, którego nie można wyrzucić:class cn extends exception{private cn(){}}
John Dvorak,

85

Z takim wyjątkiem byłoby oczywiście obowiązkowe użycie System.exit(Integer.MIN_VALUE);konstruktora, ponieważ tak by się stało, gdybyś rzucił taki wyjątek;)


32
+1; IMO to jedyne możliwe rozwiązanie. Nieuchwytnym wyjątek powinien zakończyć program ...
home

7
Nie, nie byłoby tak, gdy rzucisz taki wyjątek. Nieprzechwycony wyjątek zakończy pojedynczy wątek, nie opuści jvm, w niektórych kontekstach sam System.exit spowoduje nawet SecurityException - nie każdy fragment kodu może zamknąć program.
josefx

3
Możesz użyć while(true){}zamiast System.exit().
Piotr Praszmo,

2
w rzeczywistości możesz uniemożliwić System.exit()pracę, instalując menedżera bezpieczeństwa, który go zabrania. zmieniłoby to konstruktor w inny wyjątek (SecurityException), który mógł zostać przechwycony.
jtahlborn,

5
Umm, technicznie rzecz biorąc nigdy nie rzuciłeś wyjątku. Nie zbudowałeś jeszcze obiektu do rzucenia!
Thomas Eding,

46

Każdy kod może złapać Throwable. Więc nie, jakikolwiek wyjątek, który stworzysz, będzie podklasą Throwable i będzie podlegał złapaniu.


11
Throwable hangsam spróbowałby złapać
ChuckaNorrisa Wyjątek

35
public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(To prawda, że technicznie ten wyjątek nigdy nie jest generowany, ale ChuckNorrisExceptionnie można go wyrzucić - rzuca cię pierwszy).


4
Mój kolega zasugerował trzymanie się „dla (;;) {}”, ponieważ czuł, że połączenie „System.exit (1)” może spowodować wyjątek bezpieczeństwa. Głosuję za kreatywnością!
Phil Street,

Zgadzam się z końcem twojej odpowiedzi. Nigdy nie zadzieraj z ChuckNorris, wyjątek lub nie.
Benj

28

Każdy rzucony wyjątek musi przedłużać Throwable, aby zawsze można go było złapać. Więc odpowiedź brzmi nie.

Jeśli chcesz, aby to trudne w obsłudze, można przesłonić metody getCause(), getMessage(), getStackTrace(), toString()aby rzucić inny java.lang.ChuckNorrisException.


2
Hmm, catch (Throwable t) wywołać jakieś metody lub w inny sposób mutować obiekt? Może być możliwe spowodowanie, że klauzula catch wyśle ​​dalej wyjątek, który uniemożliwi to.
Colton

1
Myślę, że catch(Throwable t)przechowuje go tylko w zmiennej, więc moje sugestie mają zastosowanie tylko w następnym bloku, gdy użytkownik chce poradzić sobie z wyjątkiem
mirelon,

24

Moja odpowiedź opiera się na pomyśle @ jtahlborn, ale jest to w pełni działający program Java , który można spakować do pliku JAR , a nawet wdrożyć na ulubionym serwerze aplikacji jako część aplikacji internetowej .

Po pierwsze, zdefiniujmy ChuckNorrisExceptionklasę, aby nie powodowała awarii JVM od samego początku (Chuck naprawdę uwielbia zawieszanie JVM BTW :)

package chuck;

import java.io.PrintStream;
import java.io.PrintWriter;

public class ChuckNorrisException extends Exception {

    public ChuckNorrisException() {
    }

    @Override
    public Throwable getCause() {
        return null;
    }

    @Override
    public String getMessage() {
        return toString();
    }

    @Override
    public void printStackTrace(PrintWriter s) {
        super.printStackTrace(s);
    }

    @Override
    public void printStackTrace(PrintStream s) {
        super.printStackTrace(s);
    }
}

Teraz idzie Expendablesklasa, aby go zbudować:

package chuck;

import javassist.*;

public class Expendables {

    private static Class clz;

    public static ChuckNorrisException getChuck() {
        try {
            if (clz == null) {
                ClassPool pool = ClassPool.getDefault();
                CtClass cc = pool.get("chuck.ChuckNorrisException");
                cc.setSuperclass(pool.get("java.lang.Object"));
                clz = cc.toClass();
            }
            return (ChuckNorrisException)clz.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

I w końcu Mainklasa skopała tyłek:

package chuck;

public class Main {

    public void roundhouseKick() throws Exception {
        throw Expendables.getChuck();
    }

    public void foo() {
        try {
            roundhouseKick();
        } catch (Throwable ex) {
            System.out.println("Caught " + ex.toString());
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("before");
            new Main().foo();
            System.out.println("after");
        } finally {
            System.out.println("finally");
        }
    }
}

Skompiluj i uruchom go za pomocą następującego polecenia:

java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main

Otrzymasz następujące dane wyjściowe:

before
finally

Nic dziwnego - w końcu to kopnięcie wkoło :)


bardzo dobrze! sam niewiele zrobiłem z manipulacją definicją klasy. czy nadal potrzebujesz „Verify: none” w wierszu poleceń?
jtahlborn,

@jtahlborn Tak, próba wyrzucenia obiektu niebędącego potomkiem Throwable kończy się niepowodzeniem bez „Verify: none”.
Wildfire,

och, mam wrażenie, że to jakoś ominęło to ograniczenie. więc czym to różni się od mojej odpowiedzi?
jtahlborn,

2
Główną różnicą jest to, że działa kod Java bez hakowania w czasie kompilacji
Wildfire

15

W konstruktorze możesz uruchomić wątek, który wielokrotnie wywołuje originalThread.stop (ChuckNorisException.this)

Wątek mógł wielokrotnie wychwytywać wyjątek, ale rzucałby go aż do śmierci.


13

Nie. Wszystkie wyjątki w Javie muszą być podklasowane java.lang.Throwablei chociaż może to nie być dobrą praktyką, możesz wychwycić każdy typ wyjątku:

try {
    //Stuff
} catch ( Throwable T ){
    //Doesn't matter what it was, I caught it.
}

Zobacz uzyskać więcej informacji, dokumentację java.lang.Throwable .

Jeśli próbujesz uniknąć zaznaczonych wyjątków ( wyjątków , które muszą być jawnie obsługiwane), możesz podklasę Błąd lub RuntimeException.


9

W rzeczywistości zaakceptowana odpowiedź nie jest tak ładna, ponieważ Java musi być uruchomiona bez weryfikacji, tzn. Kod nie działałby w normalnych okolicznościach.

AspectJ na ratunek dla prawdziwego rozwiązania !

Klasa wyjątków:

package de.scrum_master.app;

public class ChuckNorrisException extends RuntimeException {
    public ChuckNorrisException(String message) {
        super(message);
    }
}

Aspekt:

package de.scrum_master.aspect;

import de.scrum_master.app.ChuckNorrisException;

public aspect ChuckNorrisAspect {
    before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
        System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
        throw chuck;
    }
}

Przykładowa aplikacja:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        catchAllMethod();
    }

    private static void catchAllMethod() {
        try {
            exceptionThrowingMethod();
        }
        catch (Throwable t) {
            System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
        }
    }

    private static void exceptionThrowingMethod() {
        throw new ChuckNorrisException("Catch me if you can!");
    }
}

Wynik:

Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
    at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
    at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
    at de.scrum_master.app.Application.main(Application.java:5)

8

Wariantem tego motywu jest zaskakujący fakt, że można rzucać niezadeklarowane sprawdzone wyjątki od kodu Java. Ponieważ nie jest zadeklarowany w podpisie metod, kompilator nie pozwala na przechwycenie samego wyjątku, chociaż można go przechwycić jako java.lang.Exception.

Oto klasa pomocnicza, która pozwala rzucać wszystko, zadeklarowane lub nie:

public class SneakyThrow {
  public static RuntimeException sneak(Throwable t) {
    throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
  }

  private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
    throw (T) t;
  }
}

Teraz throw SneakyThrow.sneak(new ChuckNorrisException());generuje wyjątek ChuckNorrisException, ale kompilator narzeka

try {
  throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}

o przechwytywaniu wyjątku, który nie jest zgłaszany, jeśli wyjątek ChuckNorrisException jest sprawdzonym wyjątkiem.


6

Jedynymi ChuckNorrisExceptionliterami w Javie powinny być OutOfMemoryErrori StackOverflowError.

Możesz faktycznie „złapać” je w sposób, który oznacza catch(OutOfMemoryError ex) wykona się w przypadku zgłoszenia wyjątku, ale blok ten automatycznie zwróci wyjątek dzwoniącemu.

Nie sądzę, że to wystarcza, public class ChuckNorrisError extends Errorale możesz spróbować. Nie znalazłem dokumentacji dotyczącej rozszerzeniaError


2
Błąd wciąż rozszerza Throwable, więc nie ma sposobu, aby go nie złapać. Jest to zgodne z projektem języka Java.
JasonM1

1
@ JasonM1 Nie sądzę, że OP poprosił o faktycznie „nie do złapania” wyjątek, a miałem na myśli, że Błąd rozprzestrzenia się, nawet jeśli go złapiesz. Tak więc każdy Throwable jest możliwy do złapania, ale te dwa ostatecznie się rozprzestrzeniają bez względu na to, co robisz
usr-local-ΕΨΗΕΛΩΝ

Aby być podstępnym, ChuckNorrisException może bezpośrednio rozszerzyć Throwable, to nie byłby to ani wyjątek, ani błąd!
JasonM1

4
Błąd nie rozprzestrzenia się, nawet jeśli go złapiesz, nie jestem pewien, skąd wziął się ten pomysł.
jtahlborn,

3
Myślę, że jesteś bardzo zdezorientowany co do Errosa, są to normalne wyjątki, takie jak wszystko, co rozszerza sam Thromble, a nawet Throwable.
bestsss

6

Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?

Tak, a oto odpowiedź: Zaprojektuj java.lang.ChuckNorrisExceptiontaki, aby nie był to przypadek java.lang.Throwable. Dlaczego? Obiekt niemożliwy do zdefiniowania jest z definicji nie do złapania, ponieważ nigdy nie można złapać czegoś, czego nigdy nie można wyrzucić.


2
Ale to nie jest wyjątek.
dolbi

8
@dolbi: Nie mogę znaleźć miejsca w pytaniu OP, że stany java.lang.ChuckNorrisExceptionmuszą być wyjątkiem, nie mówiąc już o rzucaniu
Thomas Eding,

1
Chyba nie jest to powiedziane, ale jest implikowane. Jesteś matematykiem :-), prawda?
dolbi

3

Możesz zachować ChuckaNorrisa wewnętrznie lub prywatnie i obudować go lub pochłonąć ...

try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }


7
Nie sądzę, żeby chodziło o to, żeby to złapać. Myślę, że chodzi o to, aby zapobiec jego złapaniu.
Patrick Roberts,

Popraw mnie, jeśli się mylę, ale jeśli uczynisz to wewnętrznym, nie możesz do tego dojść bez refleksji.
Jay,

5
tak, ale tak długo, jak można złapać wyjątek lub Throwable, widoczność rzeczywistego typu jest nieistotna.
KeithS,

3

Dwa podstawowe problemy z obsługą wyjątków w Javie polegają na tym, że używa on typu wyjątku, aby wskazać, czy należy na nim podjąć działanie, i że zakłada się, że wszystko, co podejmuje działanie w oparciu o wyjątek (tj. „Przechwytuje” to) warunek podstawowy. Przydatne byłoby posiadanie środków, dzięki którym obiekt wyjątku mógłby decydować, które procedury obsługi powinny zostać wykonane i czy procedury obsługi, które do tej pory wykonały, wyczyściły wszystko wystarczająco, aby obecny sposób mógł spełnić warunki wyjścia. Chociaż można tego użyć do stworzenia „niemożliwych do uchwycenia” wyjątków, dwa większe zastosowania to (1) wprowadzenie wyjątków, które będą rozpatrywane tylko wtedy, gdy zostaną przechwycone przez kod, który faktycznie wie, jak sobie z nimi poradzić, i (2) zezwolą do rozsądnego obchodzenia się z wyjątkami, które występują wfinallyFooExceptionpodczas finallybloku podczas odwijania a BarExceptionoba wyjątki powinny propagować stos wywołań; oba powinny być możliwe do złapania, ale rozwijanie powinno trwać, dopóki nie zostaną złapane). Niestety nie sądzę, aby istniał jakiś sposób, aby istniejący kod obsługi wyjątków działał w ten sposób bez zepsucia rzeczy.


ciekawy pomysł, ale nie sądzę, że kod niskiego poziomu wiedziałby, co konkretny wyjątek „oznacza” dla dzwoniącego, więc nie sądzę, aby rzucający decydował, które programy obsługi powinny zostać wykonane.
jtahlborn,

@jtahlborn: W tej chwili rzucający decyduje, które procedury obsługi wyjątków powinny zostać wykonane poprzez wybór typu wyjątku. To sprawia, że ​​praktycznie niemożliwe jest czyste zarządzanie niektórymi scenariuszami. Między innymi: (1) jeśli wyjątek wystąpi podczas finallyczyszczenia bloku z wcześniejszego wyjątku, jest całkiem możliwe, że którykolwiek wyjątek, przy braku drugiego, może być czymś, co kod mógłby obsłużyć i kontynuować, ale radzenie sobie z jednym i ignorowanie drugiego byłoby złe. Nie ma jednak mechanizmu generowania złożonego wyjątku, który przetworzyłyby oba programy obsługi.
supercat

@ jtahlborn: Utrudnia to również obsługę wyjątków występujących w wywołaniach zwrotnych przez zewnętrzną warstwę aplikacji. Jeśli wyjątek wywołania zwrotnego jest zawinięty w inny typ wyjątku, nie można użyć typu wyjątku wywołania zwrotnego w warstwie zewnętrznej przy podejmowaniu decyzji, czy go złapać; jeśli nie jest zawinięty, „przypadkowy” wyjątek warstwy środkowej może zostać pomylony z wyjątkiem występującym w wywołaniu zwrotnym. Jeśli zawinięty obiekt wyjątku zostanie powiadomiony, gdy zostanie przekazany do zewnętrznej warstwy aplikacji, wówczas może zacząć odpowiadać na typy zawiniętych wyjątków.
supercat

nie dyskutowałem o twoich innych punktach, tylko stwierdzenie o obiekcie wyjątku decydującym o tym, które programy obsługi będą wykonywane. do pewnego stopnia typy wyjątków już to robią, ale brzmi to tak, jakbyś chciał czegoś bardziej dynamicznego, z czym się nie zgadzałem. myślę, że twoim głównym argumentem (który w pewnym sensie przychodzisz na boki) jest uchwycenie jak największej ilości informacji na dole i pozwolenie, aby górne warstwy zobaczyły i pracowały z tymi wszystkimi informacjami. w tej ogólnej kwestii zgadzam się z tobą, jednak diabeł tkwi w szczegółach / realizacji.
jtahlborn,

@ jtahlborn: Moim zamiarem nie było, aby wirtualne metody implementowały coś szczególnie „dynamicznego”, ale w zasadzie powiedzieć „Czy istnieje warunek wskazanego typu, na który należy zareagować”. Jedną rzecz, o której zapomniałem wspomnieć, jest to, że powinien istnieć sposób, za pomocą którego kod wywołujący Foomoże odróżnić wyjątek, który Fooalbo sam się rzucił, albo celowo chce udawać, że sam się rzucił, od tego, któryFoo nie spodziewał się, że nastąpi wywołanie innej metody. Właśnie tym pojęciem „sprawdzonych” wyjątków powinno być „około”.
supercat

1

Łatwo jest zasymulować niewyłapany wyjątek dla bieżącego wątku. Spowoduje to normalne zachowanie nieprzechwyconego wyjątku, a tym samym wykonanie zadania semantycznie. Niekoniecznie jednak zatrzyma to wykonywanie bieżącego wątku, ponieważ tak naprawdę nie zostanie zgłoszony żaden wyjątek.

Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
    currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.

Jest to faktycznie przydatne w (bardzo rzadkich) sytuacjach, na przykład gdy Errorwymagana jest poprawna obsługa, ale metoda jest wywoływana z frameworka, który przechwytuje (i odrzuca) dowolne Throwable.


0

Wywołaj System.exit (1) w finalizei po prostu wyrzuć kopię wyjątku ze wszystkich innych metod, aby program się zakończył.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.