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 .
java
exception
exception-handling
aop
Max Charas
sumber
sumber
finalize()
?Jawaban:
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 kelasChuckNorrisException
yang tidak memperpanjang Throwable .MEMPERBARUI:
Itu tidak bekerja. Ini menghasilkan kesalahan verifikasi:
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:
Kompilasi kelas:
Lari:
Mengomentari "extends RuntimeException" dan hanya mengkompilasi ulang
ChuckNorrisException.java
:Lari:
Jalankan tanpa verifikasi:
sumber
Object
bukanThrowable
? (Kompilator tidak akan mengizinkannya, tetapi karena kami telah menonaktifkan verifier, mungkin seseorang dapat meretas bytecode untuk melakukannya.)Setelah merenungkan ini, saya berhasil membuat pengecualian yang tidak dapat ditandingi. Saya memilih untuk
JulesWinnfield
menamainya, 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:Et voila! Pengecualian tanpa tertangkap.
Keluaran:
Ketika saya memiliki sedikit waktu lagi, saya akan melihat apakah saya tidak dapat menemukan sesuatu yang lain juga.
Juga, lihat ini:
Menyebabkan stack overflow - lagi, pengecualian tetap tidak tertangkap.
sumber
JulesWinfield
? Bukankah sistem akan berhenti melengking sebelum dilempar?throw new Whatever()
ini benar-benar dua bagian:,Whatever it = new Whatever(); throw it;
dan sistem mati sebelum mencapai bagian kedua.class cn extends exception{private cn(){}}
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;)sumber
while(true){}
bukanSystem.exit()
.System.exit()
bekerja dengan menginstal manajer keamanan yang melarangnya. yang akan mengubah konstruktor menjadi pengecualian berbeda (SecurityException), yang dapat ditangkap.Kode apa pun dapat menangkap Throwable. Jadi tidak, pengecualian apa pun yang Anda buat akan menjadi subkelas Throwable dan akan ditangkap.
sumber
hang
berusaha menangkap ChuckNorrisException: P(Memang, secara teknis pengecualian ini tidak pernah benar-benar dilemparkan, tetapi suatu hak
ChuckNorrisException
tidak dapat dilempar - itu melempar Anda terlebih dahulu.)sumber
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 lainjava.lang.ChuckNorrisException
.sumber
catch(Throwable t)
hanya menyimpannya ke dalam variabel sehingga saran saya hanya berlaku di blok berikutnya ketika pengguna ingin mengatasi pengecualianJawaban 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
ChuckNorrisException
kelas agar tidak crash JVM dari awal (Chuck sangat suka menabrak JVMs BTW :)Sekarang masuk
Expendables
kelas untuk membangunnya:Dan akhirnya
Main
kelas menendang pantat:Kompilasi dan jalankan dengan perintah berikut:
Anda akan mendapatkan hasil sebagai berikut:
Tidak mengherankan - ini adalah tendangan lokomotif :)
sumber
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.
sumber
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: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.
sumber
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:
Aspek:
Contoh aplikasi:
Keluaran:
sumber
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:
Sekarang
throw SneakyThrow.sneak(new ChuckNorrisException());
tidak melempar ChuckNorrisException, tetapi kompiler mengeluhtentang menangkap pengecualian yang tidak dilemparkan jika ChuckNorrisException adalah pengecualian yang diperiksa.
sumber
Satu-satunya
ChuckNorrisException
di Jawa harusOutOfMemoryError
danStackOverflowError
.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 Error
tetapi Anda bisa mencobanya. Saya tidak menemukan dokumentasi tentang perpanjanganError
sumber
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.ChuckNorrisException
sedemikian rupa sehingga bukan turunan darijava.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.sumber
java.lang.ChuckNorrisException
harus menjadi pengecualian, apalagi yang bisa dibuangAnda dapat menjaga ChuckNorris internal atau pribadi dan merangkumnya atau mengikuti ...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
sumber
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,
finally
FooException
finally
blok selama pelepasan aBarException
, 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.sumber
finally
blok 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.Foo
dapat membedakan antara pengecualian yangFoo
melemparkan sendiri atau sengaja ingin berpura-pura melemparkan sendiri, dari yangFoo
tidak diharapkan terjadi ketika itu memanggil beberapa metode lain. Itulah yang seharusnya menjadi pengecualian "dicentang".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.
Ini sebenarnya berguna dalam situasi (sangat jarang), misalnya ketika
Error
penanganan yang tepat diperlukan, tetapi metode ini diambil dari kerangka kerja menangkap (dan membuang) apa punThrowable
.sumber
Panggil System.exit (1) di
finalize
, dan hanya membuang salinan pengecualian dari semua metode lain, sehingga program akan keluar.sumber