Pertanyaan Pertanyaan Penanganan Eksepsi


Saya punya pertanyaan tentang penanganan pengecualian. Pertimbangkan mengikuti potongan kode Java.

        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }

Saya tahu ini adalah cara yang disarankan untuk menangani pengecualian. Tetapi saya dapat mencapai hal yang sama dengan menggunakan cuplikan kode berikut.

        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }

Bisakah seseorang memberitahuku kerugian dari pendekatan kedua?


31
2018-02-22 05:21


asal


Jawaban:


Pendekatan kedua kurang bisa dibaca. Selain penanganan pengecualian Pokemon tidak pernah jalan untuk pergi meskipun trik "pintar" Anda adalah dengan menggunakan kata kunci instanceof. Saya tidak mengolok-olok atau mengejek Anda, tetapi yang terbaik adalah menulis kode agar manusia dapat membaca dan memelihara, bukan untuk komputer.


110
2018-02-22 05:24



Ya, MadMurf menunjukkan perbedaan yang paling penting: pengecekan reachability pada waktu kompilasi. Idiom standar akan menangkap sesuatu seperti ini dan mencegahnya dari kompilasi:

    try {
    } catch (IndexOutOfBoundsException iooe) {
    } catch (ArrayIndexOutOfBoundsException aiooe) {
    }

If / instanceof analog yang diusulkan dalam pertanyaan asli akan mengkompilasi (yang BUKAN apa yang Anda inginkan karena itu salah).

Alasan mengapa idiom standar menangkap kesalahan pada waktu kompilasi diberikan JLS 14.21 Laporan yang Tidak Terjadi.

  • Blok tangkap C dapat dicapai jika kedua hal berikut ini benar:      
    • [...]
    • Tidak ada blok tangkapan sebelumnya A dalam pernyataan coba sehingga jenis parameter C sama dengan atau subkelas dari tipe parameter A.

Untuk mengilustrasikan lebih jauh, berikut ini kompilasi:

    try {
    } catch (Exception e) {
        if (e instanceof Exception) {
        } else if (e instanceof Exception) {
        }
    }

Seperti yang Anda lihat, idiom "pokemon catching" ini jauh lebih sulit untuk dipertahankan karena mengeliminasi beberapa pemeriksaan reachability waktu yang ditegakkan dalam idiom standar.

Untuk lebih jelas lagi, apakah Anda sengaja atau tidak, Anda sebenarnya menyusun ulang urutan di mana Anda memeriksa pengecualian dalam pertanyaan awal Anda, sebuah fakta yang dapat dengan mudah dilewatkan oleh orang lain. Jika SubSubException adalah subkelas dari SubException, kondisi kedua jika TIDAK PERNAH dievaluasi, dan tubuhnya adalah kode yang tidak terjangkau.

Pendekatan if / instance dari SANGAT rentan terhadap kesalahan.


39
2018-02-22 08:04



hmm, mengapa Anda bahkan harus melakukan pendekatan kedua? ingat ini, kecuali opsi lain lebih baik dalam hal kinerja, keterbacaan, dll, Anda harus tetap dengan konvensi. Pernyataan tangkap awalnya dirancang sehingga mereka menangani klasifikasi jenis pengecualian memiliki mereka sendiri sehingga menggunakan mereka seperti ... hanya sebuah pemikiran! ...


22
2018-02-22 05:29



Kasus kedua adalah kode java yang sangat valid, tetapi memiliki lebih besar Cyclomatic complexity tanpa menambahkan nilai ekstra.


4
2018-02-22 05:35



Pendekatan kedua secara signifikan lebih mudah dibaca karena:

  • itu membutuhkan lebih banyak simbol,

  • itu membutuhkan indentasi yang lebih dalam,

  • itu tidak idiomatik.

Dan IMO, yang terakhir adalah yang paling penting. Anda harus menulis kode Anda dengan cara yang lain Programmer Java berharap itu ditulis.


4
2018-02-22 05:37



Sebagai tambahan dalam memesan kembali "penangkapan" pengecualian dalam contoh kedua Anda. Jika SubSubException memperluas SubException, cek kedua tidak akan pernah tercapai ....

hanya sesuatu yang harus diwaspadai ketika memesan tangkapan Anda ...

selain dari yang disebutkan di tempat lain, pertanyaannya adalah mengapa mencoba cara kedua ketika karya pertama, adalah standar dan dapat dibaca?


2
2018-02-22 05:33



Mempertimbangkan kode di blok pertama menguji jenis pengecualian, uji untuk pengecualian basis sekali (dalam bit kedua kode yang Anda uji untuk basis Pengecualian dua kali dengan cara) dan kurang indentasi (sehingga kurang logika untuk grok) , pikiran saya adalah yang pertama jauh lebih baik, lebih mudah dimengerti, dll.

Kekurangan: - Lebih sulit dimengerti


1
2018-02-22 05:30



Saya pikir, lebih baik (banyak dibaca):

 try {    
   .....
 } 
 catch (IndexOutOfBoundsException iooe) {    } 
 catch (ArrayIndexOutOfBoundsException aiooe) {    }
 .....

dan

  try {
     .....
  } 
  catch (Exception e) {
     if (e instanceof Exception) {        } else 
     if (e instanceof Exception) {        } else
     .....
  }

1
2017-07-04 19:33