ChuckNorrisException yang tak tertandingi

596

Apakah mungkin untuk membuat potongan kode di Jawa yang akan membuat hipotesa tidak cocok java.lang.ChuckNorrisException?

Pikiran yang datang ke pikiran menggunakan misalnya pencegat atau pemrograman berorientasi aspek .

Max Charas
sumber
2
menggunakan saran dari tautan @jschoen yang disediakan (nonaktifkan verifier kode byte) Anda dapat melempar sesuatu yang tidak memperpanjang Throwable! dijelaskan dalam jawaban saya di bawah ini.
jtahlborn
4
Kutipan dari jawaban aioobe ini meringkas pertanyaan @jschoen yang terhubung dengan cukup baik: "Ya, pertanyaan Anda dapat diartikan sebagai 'Jika JVM menyimpang dari spesifikasi, dapatkah ia melakukan hal-hal aneh seperti melempar orang primitif' dan jawabannya tentu saja, Iya."
Dan Is Fiddling By Firelight
2
@ Max - Bisakah Anda menguraikan penggunaan praktis untuk ini?
Vineet Bhatia
3
bagaimana dengan pengecualian yang rethrow sendiri pada finalize()?
Lie Ryan

Jawaban:

314

Saya belum mencoba ini, jadi saya tidak tahu apakah JVM akan membatasi sesuatu seperti ini, tapi mungkin Anda bisa mengkompilasi kode yang melempar ChuckNorrisException, tetapi saat runtime memberikan definisi kelas ChuckNorrisExceptionyang tidak memperpanjang Throwable .

MEMPERBARUI:

Itu tidak bekerja. Ini menghasilkan kesalahan verifikasi:

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.

PEMBARUAN 2:

Sebenarnya, Anda bisa membuatnya berfungsi jika Anda menonaktifkan verifikasi kode byte! (-Xverify:none )

PEMBARUAN 3:

Untuk yang mengikuti dari rumah, inilah skrip lengkapnya:

Buat kelas-kelas berikut:

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.");
        }
    }
}

Kompilasi kelas:

javac -cp . TestVillain.java ChuckNorrisException.java

Lari:

java -cp . TestVillain
Gotcha!
The end.

Mengomentari "extends RuntimeException" dan hanya mengkompilasi ulangChuckNorrisException.java :

javac -cp . ChuckNorrisException.java

Lari:

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.

Jalankan tanpa verifikasi:

java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
jtahlborn
sumber
18
OK, jadi bagaimana jika Anda menangkap Objectbukan Throwable? (Kompilator tidak akan mengizinkannya, tetapi karena kami telah menonaktifkan verifier, mungkin seseorang dapat meretas bytecode untuk melakukannya.)
Ilmari Karonen
11
Menurut What can you throw in Java, Anda masih bisa menangkap hal-hal yang tidak bisa diperpanjang, tetapi melempar dan menangkapnya adalah perilaku yang tidak terdefinisi.
VolatileDream
8
@ Dzieciou Mereka bisa benar bersama. Anda mungkin dapat menangkap mereka menggunakan versi lingkungan Java Anda pada versi spesifik sistem operasi Anda pada jenis prosesor Anda. Tetapi jika tidak ditentukan dalam standar apakah BISA ditangkap, itu disebut perilaku tidak terdefinisi, karena implementasi lain dari Jawa mungkin memilih untuk membuatnya tidak dapat ditangkap.
heinrich5991
2
Hmmh. Saya berharap untuk 176 upvotes, Anda telah menulis beberapa kode JNI yang menambal monyet seluruh tumpukan panggilan untuk memikirkan kembali pengecualian Anda (tentu saja disebut oleh ctor).
kdgregory
3
Ketika melakukan semua ini, itu juga ide bagus untuk berdiri dengan satu kaki, menepuk-nepuk kepala Anda dan menggosok perut Anda sambil bersiul dixie ...;);)
Glen Best
120

Setelah merenungkan ini, saya berhasil membuat pengecualian yang tidak dapat ditandingi. Saya memilih untuk JulesWinnfieldmenamainya, daripada Chuck, karena itu adalah salah satu pengecualian ibu-jamur-cloud-laying. Selain itu, mungkin tidak persis apa yang ada dalam pikiran Anda, tetapi tentu saja tidak dapat ditangkap. Mengamati:

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");
    }
}

Et voila! Pengecualian tanpa tertangkap.

Keluaran:

Lari:

Katakan 'Apa' lagi! Aku menantangmu! Saya gandakan Anda berani!

Hasil Jawa: 8

BUILD SUCCESSFUL (total waktu: 0 detik)

Ketika saya memiliki sedikit waktu lagi, saya akan melihat apakah saya tidak dapat menemukan sesuatu yang lain juga.

Juga, lihat ini:

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)
    {

    }
}

Menyebabkan stack overflow - lagi, pengecualian tetap tidak tertangkap.

MikeTheLiar
sumber
32
+1 untuk menggunakan Stack Overflow dalam jawaban Anda. Hanya bercanda, jawaban yang sangat bagus.
Yosia
7
"Pengecualian tak tertandingi" yang tepat akan memastikan bahwa semua penutup akhirnya blok akan dieksekusi tanpa ada tangkapan intervensi. Membunuh sistem tidak menimbulkan pengecualian - hanya membunuh sistem.
supercat
4
Bagaimana Anda "melempar" itu JulesWinfield? Bukankah sistem akan berhenti melengking sebelum dilempar?
supercat
6
@ MikeTheLiar: Sistem keluar selama konstruktor, bukan? Pernyataan throw new Whatever()ini benar-benar dua bagian:, Whatever it = new Whatever(); throw it;dan sistem mati sebelum mencapai bagian kedua.
supercat
5
@ MikeTheLiar Anda sebenarnya bisa menangkap Jules atau Vincent dengan mudah ... jika Anda berhasil melemparnya. Sangat mudah untuk membuat pengecualian yang tidak dapat Anda lemparkan:class cn extends exception{private cn(){}}
John Dvorak
85

Dengan pengecualian seperti itu jelas akan wajib untuk menggunakan System.exit(Integer.MIN_VALUE);dari konstruktor karena ini adalah apa yang akan terjadi jika Anda melemparkan pengecualian seperti itu;)

Korgen
sumber
32
+1; IMO ini adalah satu-satunya solusi yang mungkin. Pengecualian yang tidak dapat ditandingi akan menghentikan program ...
home
7
Tidak, itu tidak akan menjadi apa yang terjadi ketika Anda melemparkan pengecualian seperti itu. Pengecualian tanpa tertangkap akan menghentikan utas tunggal, itu tidak akan keluar dari jvm, dalam beberapa konteks System.exit itu sendiri bahkan akan menyebabkan SecurityException - tidak setiap bagian dari kode diizinkan untuk mematikan suatu program.
josefx
3
Anda bisa menggunakan while(true){}bukan System.exit().
Piotr Praszmo
2
sebenarnya, Anda dapat mencegah System.exit()bekerja dengan menginstal manajer keamanan yang melarangnya. yang akan mengubah konstruktor menjadi pengecualian berbeda (SecurityException), yang dapat ditangkap.
jtahlborn
5
Umm, secara teknis Anda tidak pernah melempar pengecualian. Anda bahkan belum membuat objek untuk dilempar!
Thomas Eding
46

Kode apa pun dapat menangkap Throwable. Jadi tidak, pengecualian apa pun yang Anda buat akan menjadi subkelas Throwable dan akan ditangkap.

Nathan Hughes
sumber
11
Throwable akan hangberusaha menangkap ChuckNorrisException: P
PermGenError
35
public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(Memang, secara teknis pengecualian ini tidak pernah benar-benar dilemparkan, tetapi suatu hak ChuckNorrisExceptiontidak dapat dilempar - itu melempar Anda terlebih dahulu.)

halus
sumber
4
Seorang kolega saya menyarankan untuk tetap menggunakan 'for (;;) {}' ketika dia merasakan panggilan 'System.exit (1)' dapat menimbulkan Pengecualian Keamanan. Saya memilih yang satu ini untuk kreativitas!
Phil Street
Saya setuju dengan akhir jawaban Anda. Jangan pernah mengacaukan ChuckNorris, Pengecualian atau tidak.
Benj
28

Pengecualian apa pun yang Anda lemparkan harus memperpanjang Throwable, sehingga dapat selalu ditangkap. Jadi jawabannya tidak.

Jika Anda ingin membuat sulit untuk menangani, Anda dapat mengganti metode getCause(), getMessage(), getStackTrace(), toString()membuang yang lain java.lang.ChuckNorrisException.

mukjizat
sumber
2
Hmm, tangkap (Throwable t) memanggil metode apa pun atau bermutasi objek? Dimungkinkan untuk menyebabkan klausa tangkapan untuk lebih lanjut melemparkan pengecualian karenanya tidak memungkinkan.
Colton
1
Saya pikir catch(Throwable t)hanya menyimpannya ke dalam variabel sehingga saran saya hanya berlaku di blok berikutnya ketika pengguna ingin mengatasi pengecualian
mirelon
24

Jawaban saya didasarkan pada ide @ jtahlborn, tetapi ini adalah program Java yang berfungsi penuh , yang dapat dikemas dalam file JAR dan bahkan digunakan untuk server aplikasi favorit Anda sebagai bagian dari aplikasi web .

Pertama-tama, mari kita tentukan ChuckNorrisExceptionkelas agar tidak crash JVM dari awal (Chuck sangat suka menabrak JVMs 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);
    }
}

Sekarang masuk Expendableskelas untuk membangunnya:

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);
        }
    }
}

Dan akhirnya Mainkelas menendang pantat:

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");
        }
    }
}

Kompilasi dan jalankan dengan perintah berikut:

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

Anda akan mendapatkan hasil sebagai berikut:

before
finally

Tidak mengherankan - ini adalah tendangan lokomotif :)

Kebakaran
sumber
sangat bagus! belum banyak melakukan manipulasi definisi kelas. apakah Anda masih memerlukan "verifikasi: tidak ada" di commandline?
jtahlborn
@ jtahlborn Ya, upaya untuk melempar objek yang bukan keturunan Throwable gagal tanpa "verifikasi: tidak ada".
Wildfire
oh, saya mendapat kesan ini entah bagaimana berhasil mengatasi kendala itu. jadi bagaimana ini berbeda dari jawaban saya?
jtahlborn
2
Perbedaan utama adalah bahwa itu berfungsi kode java tanpa kompilasi-waktu peretasan
Wildfire
15

Di konstruktor, Anda dapat memulai utas yang berulang kali memanggil originalThread.stop (ChuckNorisException.this)

Utas dapat menangkap pengecualian berulang kali tetapi akan terus melemparkannya sampai mati.

Peter Lawrey
sumber
13

Tidak. Semua pengecualian di Jawa harus subkelas java.lang.Throwable, dan meskipun ini mungkin bukan praktik yang baik, Anda dapat menangkap setiap jenis pengecualian seperti:

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

Lihat java.lang.Terima kasih dokumentasi untuk informasi lebih lanjut.

Jika Anda mencoba untuk menghindari pengecualian yang dicentang (yang harus ditangani secara eksplisit) maka Anda ingin subkelas Kesalahan, atau RuntimeException.

VolatileDream
sumber
9

Sebenarnya jawaban yang diterima tidak begitu baik karena Java harus dijalankan tanpa verifikasi, yaitu kode tidak akan berfungsi dalam keadaan normal.

Berusaha menyelamatkan dari solusi nyata !

Kelas pengecualian:

package de.scrum_master.app;

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

Aspek:

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;
    }
}

Contoh aplikasi:

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!");
    }
}

Keluaran:

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)
Kriegaex
sumber
8

Varian pada tema adalah fakta mengejutkan bahwa Anda dapat membuang pengecualian yang tidak dideklarasikan dari kode Java. Karena tidak dinyatakan dalam metode signature, kompiler tidak akan membiarkan Anda menangkap pengecualian itu sendiri, meskipun Anda bisa menangkapnya sebagai java.lang.Exception.

Inilah kelas pembantu yang memungkinkan Anda melempar apa saja, dideklarasikan atau tidak:

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;
  }
}

Sekarang throw SneakyThrow.sneak(new ChuckNorrisException());tidak melempar ChuckNorrisException, tetapi kompiler mengeluh

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

tentang menangkap pengecualian yang tidak dilemparkan jika ChuckNorrisException adalah pengecualian yang diperiksa.

Hans-Peter Störr
sumber
6

Satu-satunya ChuckNorrisExceptiondi Jawa harus OutOfMemoryErrordan StackOverflowError.

Anda benar-benar dapat "menangkap" mereka dengan cara yang a catch(OutOfMemoryError ex) akan dieksekusi dalam kasus pengecualian dilemparkan, tetapi blok itu akan secara otomatis mengubah kembali pengecualian ke penelepon.

Saya tidak berpikir itu berhasil public class ChuckNorrisError extends Errortetapi Anda bisa mencobanya. Saya tidak menemukan dokumentasi tentang perpanjanganError

usr-local-ΕΨΗΕΛΩΝ
sumber
2
Kesalahan masih meluas Throwable sehingga tidak ada cara untuk mencegah penangkapannya. Itu dengan desain bahasa Jawa.
JasonM1
1
@ JasonM1 Saya tidak berpikir OP meminta pengecualian yang sebenarnya "tidak bisa ditandingi", dan saya maksudkan bahwa Kesalahan menyebar bahkan jika Anda menangkapnya. Jadi, semua Throwable dapat ditangkap tetapi keduanya akhirnya akan menyebar tidak peduli apa yang Anda lakukan
usr-local-ΕΨΗΕΛΩΝ
Supaya ChuckNorrisException yang rumit bisa memperluas Throwable secara langsung maka itu bukanlah Pengecualian atau Kesalahan!
JasonM1
4
Kesalahan tidak menyebar bahkan jika Anda menangkapnya, saya tidak yakin dari mana Anda mendapatkan ide itu.
jtahlborn
3
Saya pikir Anda bingung tentang Erros, mereka adalah pengecualian normal seperti segala sesuatu yang meluas Throwable atau bahkan Throwable, itu sendiri.
bestsss
6

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

Ya, dan inilah jawabannya: Desain Anda java.lang.ChuckNorrisExceptionsedemikian rupa sehingga bukan turunan dari java.lang.Throwable. Mengapa? Objek yang tidak dapat dilewati tidak dapat didefinisikan oleh definisi karena Anda tidak pernah dapat menangkap sesuatu yang tidak pernah dapat dilempar.

Thomas Eding
sumber
2
Tapi itu bukan pengecualian.
dolbi
8
@dolbi: Saya tidak dapat menemukan tempat dalam pertanyaan OP yang menyatakan java.lang.ChuckNorrisExceptionharus menjadi pengecualian, apalagi yang bisa dibuang
Thomas Eding
1
Saya kira itu tidak dinyatakan, tetapi tersirat. Anda seorang ahli matematika :-), bukan?
dolbi
3

Anda dapat menjaga ChuckNorris internal atau pribadi dan merangkumnya atau mengikuti ...

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

Jay
sumber
7
Saya tidak percaya idenya adalah untuk menangkapnya. Saya pikir idenya adalah untuk mencegah agar tidak tertangkap.
Patrick Roberts
Koreksi saya jika saya salah tetapi jika Anda membuatnya internal Anda tidak bisa mendapatkannya tanpa refleksi.
Jay
5
ya, tapi selama Anda bisa menangkap Exception atau Throwable, visibilitas tipe yang sebenarnya tidak relevan.
KeithS
3

Dua masalah mendasar dengan penanganan pengecualian di Jawa adalah bahwa ia menggunakan tipe pengecualian untuk menunjukkan apakah tindakan harus diambil berdasarkan padanya, dan bahwa apa pun yang mengambil tindakan berdasarkan pengecualian (yaitu "menangkap" itu) dianggap untuk menyelesaikan kondisi yang mendasarinya. Akan bermanfaat untuk memiliki sarana yang dengannya objek pengecualian dapat memutuskan penangan mana yang harus dieksekusi, dan apakah penangan yang telah mengeksekusi sejauh ini telah membersihkan hal-hal yang cukup untuk metode ini untuk memenuhi kondisi keluarnya. Meskipun ini dapat digunakan untuk membuat pengecualian "tak tertandingi", dua kegunaan yang lebih besar adalah (1) membuat pengecualian yang hanya akan dianggap ditangani ketika mereka ditangkap oleh kode yang benar-benar tahu cara menghadapinya,finallyFooExceptionfinally blok selama pelepasan a BarException, kedua pengecualian harus merambat ke tumpukan panggilan; keduanya harus dapat ditangkap, tetapi pelonggaran harus berlanjut sampai keduanya tertangkap). Sayangnya, saya tidak berpikir akan ada cara untuk membuat kode penanganan eksepsi yang ada berfungsi seperti itu tanpa merusak barang-barang.

supercat
sumber
ide yang menarik, tetapi saya tidak berpikir kode tingkat rendah akan tahu apa pengecualian "berarti" bagi pemanggil, jadi saya tidak berpikir itu akan masuk akal bagi pelempar untuk memutuskan penangan mana yang harus dieksekusi.
jtahlborn
@ jtahlborn: Saat ini, pelempar memutuskan penangan pengecualian apa yang harus dieksekusi melalui pilihan jenis pengecualian. Ini membuat semuanya sangat mustahil untuk menangani beberapa skenario dengan bersih. Antara lain: (1) jika pengecualian terjadi saat finallyblok membersihkan dari pengecualian sebelumnya, sangat mungkin bahwa salah satu pengecualian, tanpa adanya yang lain, mungkin sesuatu yang diharapkan akan ditangani oleh kode dan dilanjutkan, tetapi menangani satu dan mengabaikan yang lain akan buruk. Namun, tidak ada mekanisme untuk menghasilkan pengecualian gabungan yang akan diproses oleh kedua penangan.
supercat
@ jtahlborn: Juga, itu membuatnya sangat sulit untuk memungkinkan pengecualian yang terjadi di dalam callback ditangani oleh lapisan aplikasi luar. Jika pengecualian callback dibungkus dengan tipe pengecualian lain, jenis pengecualian callback tidak dapat digunakan di lapisan luar dalam memutuskan apakah akan menangkapnya; jika tidak dibungkus, pengecualian lapisan tengah "tidak disengaja" mungkin keliru dengan yang terjadi dalam panggilan balik. Jika objek pengecualian yang dibungkus diberitahu ketika dilewatkan ke lapisan aplikasi luar, maka ia bisa mulai menjawab jenis pengecualian yang dibungkus.
supercat
saya tidak memperdebatkan poin Anda yang lain, hanya pernyataan tentang objek pengecualian yang memutuskan penangan mana yang akan dieksekusi. sampai taraf tertentu jenis pengecualian sudah melakukannya, tetapi sepertinya Anda menginginkan sesuatu yang lebih dinamis, yang saya tidak setujui. Saya pikir argumen utama Anda (yang Anda agak datang ke samping) adalah untuk menangkap informasi sebanyak mungkin di bagian bawah dan membiarkan lapisan atas melihat dan bekerja dengan semua informasi itu. pada poin umum ini saya setuju dengan Anda, namun iblis ada di detail / implementasi.
jtahlborn
@ jtahlborn: Tujuan saya bukan untuk menerapkan metode virtual apa pun terutama "dinamis", tetapi pada dasarnya mengatakan "Apakah ada kondisi tipe yang ditunjukkan yang harus ditindaklanjuti". Satu hal yang saya lupa sebutkan, adalah bahwa harus ada sarana melalui mana kode yang panggilan Foodapat membedakan antara pengecualian yang Foomelemparkan sendiri atau sengaja ingin berpura-pura melemparkan sendiri, dari yang Footidak diharapkan terjadi ketika itu memanggil beberapa metode lain. Itulah yang seharusnya menjadi pengecualian "dicentang".
supercat
1

Sangat mudah untuk mensimulasikan pengecualian yang tidak tertangkap pada utas saat ini. Ini akan memicu perilaku reguler pengecualian yang tidak tertangkap, dan dengan demikian menyelesaikan pekerjaan secara semantik. Namun, itu tidak akan menghentikan eksekusi utas saat ini, karena tidak ada pengecualian yang benar-benar dilemparkan.

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

Ini sebenarnya berguna dalam situasi (sangat jarang), misalnya ketika Errorpenanganan yang tepat diperlukan, tetapi metode ini diambil dari kerangka kerja menangkap (dan membuang) apa pun Throwable.

dst
sumber
0

Panggil System.exit (1) di finalize, dan hanya membuang salinan pengecualian dari semua metode lain, sehingga program akan keluar.

Demi
sumber