Adakah Amalan Buruk untuk Menangkap Lempar?

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat implikasi menangkap Throwable .

2. Kelas Lempar

Dalam dokumentasi Java, kelas Throwable didefinisikan sebagai " kelas super dari semua kesalahan dan pengecualian dalam bahasa Java ".

Mari lihat hierarki kelas Throwable :

Yang dilontar kelas mempunyai dua sub-kelas langsung - iaitu Ralat dan Pengecualian kelas.

Ralat dan sub-kelasnya adalah pengecualian yang tidak dicentang, sementara sub-kelas Pengecualian boleh diperiksa atau tidak dikecualikan.

Mari kita lihat jenis situasi yang dapat dialami oleh program apabila gagal.

3. Keadaan yang Boleh Dipulihkan

Terdapat situasi di mana pemulihan secara amnya mungkin dan dapat ditangani dengan sub-kelas yang diperiksa atau tidak dicentang dari kelas Pengecualian .

Sebagai contoh, program mungkin ingin menggunakan fail yang kebetulan tidak ada di lokasi yang ditentukan, mengakibatkan FileNotFoundException dicentang dilemparkan.

Contoh lain adalah program yang berusaha mengakses sumber sistem tanpa izin untuk melakukannya, mengakibatkan Pengecualian AccessControl yang tidak dicentang dilemparkan.

Seperti dokumentasi Jawa, yang Pengecualian kelas "menunjukkan keadaan bahawa permohonan yang munasabah mungkin mahu menangkap ".

4. Situasi Tidak Dapat Dipulihkan

Terdapat kes di mana program dapat dalam keadaan di mana pemulihan tidak mungkin berlaku sekiranya berlaku kegagalan. Contoh yang biasa berlaku ialah apabila timbunan limpahan berlaku atau JVM kehabisan memori.

Dalam situasi ini, JVM masing-masing membuang StackOverflowError dan OutOfMemoryError . Seperti yang disarankan oleh nama mereka, ini adalah sub-kelas kelas Kesalahan .

Mengikut dokumentasi Jawa, yang Ralat kelas "menunjukkan masalah yang serius bahawa permohonan yang munasabah tidak harus cuba untuk menangkap ".

5. Contoh Situasi yang Boleh Dipulihkan dan Tidak Dapat Dipulihkan

Mari kita anggap bahawa kita mempunyai API yang membolehkan pemanggil menambahkan ID unik ke beberapa kemudahan penyimpanan menggunakan kaedah addIDsToStorage :

class StorageAPI { public void addIDsToStorage(int capacity, Set storage) throws CapacityException { if (capacity < 1) { throw new CapacityException("Capacity of less than 1 is not allowed"); } int count = 0; while (count < capacity) { storage.add(UUID.randomUUID().toString()); count++; } } // other methods go here ... }

Beberapa titik kegagalan yang berpotensi boleh berlaku semasa memanggil addIDsToStorage :

  • CapacityException - Sub-kelas Pengecualian yang diperiksa ketika melewati nilai kapasiti kurang dari 1
  • NullPointerException - Sub-kelas Pengecualian yang tidak dicentang jika nilai penyimpanan nol diberikan dan bukannya contoh Set
  • OutOfMemoryError - An sub-kelas tidak terkawal daripada Ralat jika JVM kehabisan memori sebelum keluar dari manakala gelung

The CapacityException dan NullPointerException keadaan adalah kegagalan program ini boleh pulih daripada, tetapi OutOfMemoryError adalah salah satu yang tidak dapat dipulihkan.

6. Menangkap Lempar

Mari kita anggap pengguna API hanya menangkap Throwable dalam try-catch ketika memanggil addIDsToStorage :

public void add(StorageAPI api, int capacity, Set storage) { try { api.addIDsToStorage(capacity, storage); } catch (Throwable throwable) { // do something here } }

Ini bermaksud bahawa kod panggilan bertindak balas terhadap situasi yang dapat dipulihkan dan tidak dapat dipulihkan dengan cara yang sama.

Peraturan umum dalam menangani pengecualian adalah bahawa blok tangkapan mesti seinci mungkin dalam pengecualian menangkap. Iaitu, senario tangkapan semua mesti dielakkan .

Menangkap Lempar dalam kes kami melanggar peraturan umum ini. Untuk bertindak balas terhadap situasi yang dapat dipulihkan dan tidak dapat dipulihkan secara berasingan, kod panggilan harus memeriksa keadaan objek Lempar di dalam blok tangkapan .

Cara yang lebih baik adalah dengan menggunakan pendekatan khusus dalam menangani pengecualian dan untuk tidak berusaha menghadapi situasi yang tidak dapat dipulihkan .

7. Kesimpulannya

Dalam artikel ini, kami melihat implikasi menangkap Throwable di blok try-catch .

Seperti biasa, kod sumber penuh contoh terdapat di Github.