Praktik terbaik untuk manajemen pengecualian di Java atau C # [ditutup]

117

Saya terjebak dalam memutuskan bagaimana menangani pengecualian dalam aplikasi saya.

Banyak jika masalah saya dengan pengecualian berasal dari 1) mengakses data melalui layanan jarak jauh atau 2) deserialisasi objek JSON. Sayangnya saya tidak dapat menjamin keberhasilan untuk salah satu tugas ini (koneksi jaringan terputus, objek JSON rusak yang di luar kendali saya).

Akibatnya, jika saya menemukan pengecualian, saya hanya menangkapnya di dalam fungsi dan mengembalikan FALSE ke pemanggil. Logika saya adalah bahwa semua penelepon benar-benar peduli adalah jika tugas itu berhasil, bukan mengapa itu tidak berhasil.

Berikut beberapa kode contoh (dalam JAWA) dari metode umum)

public boolean doSomething(Object p_somthingToDoOn)
{
    boolean result = false;

    try{
        // if dirty object then clean
        doactualStuffOnObject(p_jsonObject);

        //assume success (no exception thrown)
        result = true;
    }
    catch(Exception Ex)
    {
        //don't care about exceptions
        Ex.printStackTrace();
    }
    return result;
}

Saya pikir pendekatan ini baik-baik saja, tetapi saya benar-benar ingin tahu apa praktik terbaik untuk mengelola pengecualian (haruskah saya benar-benar membuat pengecualian sepanjang tumpukan panggilan?).

Ringkasan pertanyaan kunci:

  1. Bolehkah hanya menangkap pengecualian tetapi tidak melembungkannya atau memberi tahu sistem secara resmi (baik melalui log atau pemberitahuan kepada pengguna)?
  2. Praktik terbaik apa yang tersedia untuk pengecualian yang tidak mengakibatkan semua yang memerlukan blok coba / tangkap?

Tindak Lanjut / Edit

Terima kasih atas semua umpan baliknya, temukan beberapa sumber bagus tentang manajemen pengecualian online:

Tampaknya manajemen pengecualian adalah salah satu hal yang bervariasi berdasarkan konteks. Tetapi yang paling penting, seseorang harus konsisten dalam cara mereka mengelola pengecualian dalam suatu sistem.

Selain itu hati-hati terhadap pembusukan kode melalui percobaan / tangkapan yang berlebihan atau tidak memberikan pengecualian rasa hormatnya (pengecualian memperingatkan sistem, apa lagi yang perlu diperingatkan?).

Juga, ini adalah komentar pilihan cantik dari m3rLinEz .

Saya cenderung setuju dengan Anders Hejlsberg dan Anda bahwa sebagian besar penelepon hanya peduli jika operasi berhasil atau tidak.

Dari komentar ini muncul beberapa pertanyaan untuk dipikirkan ketika berhadapan dengan pengecualian:

  • Apa gunanya pengecualian ini dilemparkan?
  • Bagaimana masuk akal untuk menanganinya?
  • Apakah penelepon benar-benar peduli dengan pengecualian atau apakah mereka hanya peduli jika panggilan berhasil?
  • Apakah memaksa penelepon untuk mengelola potensi pengecualian itu anggun?
  • Apakah Anda menghormati idom bahasa tersebut?
    • Apakah Anda benar-benar perlu mengembalikan bendera sukses seperti boolean? Mengembalikan boolean (atau int) lebih merupakan pola pikir C daripada Java (di Java Anda hanya akan menangani pengecualian).
    • Ikuti konstruksi manajemen kesalahan yang terkait dengan bahasa :)!
AtariPete
sumber
Meskipun artikel dari komunitas oracle ada di java, itu saran umum untuk kelas bahasa yang sangat luas. Artikel bagus, apa yang saya cari.
Kelinci Kelinci

Jawaban:

61

Tampaknya aneh bagi saya bahwa Anda ingin menangkap pengecualian dan mengubahnya menjadi kode kesalahan. Menurut Anda mengapa pemanggil lebih memilih kode kesalahan daripada pengecualian ketika yang terakhir adalah default di Java dan C #?

Adapun pertanyaan Anda:

  1. Anda seharusnya hanya menangkap pengecualian yang benar-benar dapat Anda tangani. Hanya menangkap pengecualian bukanlah hal yang benar untuk dilakukan dalam banyak kasus. Ada beberapa pengecualian (mis. Logging dan marshalling pengecualian antar utas) tetapi bahkan untuk kasus tersebut Anda biasanya harus menampilkan kembali pengecualian.
  2. Anda seharusnya tidak memiliki banyak pernyataan coba / tangkap dalam kode Anda. Sekali lagi, idenya adalah untuk hanya menangkap pengecualian yang dapat Anda tangani. Anda dapat menyertakan penangan pengecualian paling atas untuk mengubah setiap pengecualian yang tidak tertangani menjadi sesuatu yang agak berguna bagi pengguna akhir, tetapi sebaliknya Anda tidak boleh mencoba menangkap setiap pengecualian di setiap tempat yang memungkinkan.
Brian Rasmussen
sumber
Adapun mengapa seseorang menginginkan kode kesalahan daripada pengecualian ... Saya selalu berpikir aneh bahwa HTTP masih menggunakan kode kesalahan, meskipun aplikasi saya membuat pengecualian. Mengapa HTTP tidak mengizinkan saya meneruskan pengecualian sebagaimana adanya?
Trejkaz
yang terbaik yang dapat Anda lakukan adalah membungkus kode kesalahan Anda dalam monad
lindenrovio
@Trejkaz Anda tidak ingin mengembalikan detail pengecualian kepada pengguna, karena itu adalah risiko keamanan. Inilah sebabnya mengapa server HTML mengembalikan kode kesalahan. Ini juga merupakan masalah pelokalan untuk mengembalikan pesan kesalahan, dan mungkin membuat ukuran HTML lebih besar dan lebih lambat untuk dikembalikan. Semua ini adalah mengapa menurut saya server HTML mengembalikan kode kesalahan.
Didier A.
Saya pikir lebih baik mengatakan: "Anda seharusnya hanya menekan pengecualian yang sebenarnya dapat Anda tangani."
Didier A.
@didibus Menurut Anda, mengapa masalah keamanan harus menimbulkan ketidaknyamanan dalam pengembangan? Saya tidak pernah mengatakan apapun tentang produksi. Adapun lokalisasi pesan kesalahan, seluruh situs web telah mengalami masalah itu dan orang-orang tampaknya mengatasinya.
Trejkaz
25

Ini tergantung pada aplikasi dan situasinya. Jika Anda membuat komponen library, Anda harus menampilkan pengecualian, meskipun pengecualian tersebut harus digabungkan agar kontekstual dengan komponen Anda. Misalnya jika Anda membangun Database Xml dan katakanlah Anda menggunakan sistem file untuk menyimpan data Anda, dan Anda menggunakan izin sistem file untuk mengamankan data. Anda tidak ingin menampilkan pengecualian FileIOAccessDenied karena itu membocorkan implementasi Anda. Sebagai gantinya Anda akan membungkus pengecualian dan melontarkan kesalahan AccessDenied. Ini terutama benar jika Anda mendistribusikan komponen ke pihak ketiga.

Adapun jika tidak apa-apa menelan pengecualian. Itu tergantung pada sistem Anda. Jika aplikasi Anda dapat menangani kasus kegagalan dan tidak ada manfaatnya memberi tahu pengguna mengapa gagal, lanjutkan saja, meskipun saya sangat menyarankan agar Anda mencatat kegagalan. Saya selalu merasa frustasi dipanggil untuk membantu memecahkan masalah dan menemukan mereka menelan pengecualian (atau menggantinya dan melempar yang baru sebagai gantinya tanpa mengatur pengecualian batin).

Secara umum saya menggunakan aturan berikut:

  1. Di komponen & perpustakaan saya, saya hanya menangkap pengecualian jika saya bermaksud menanganinya atau melakukan sesuatu berdasarkan itu. Atau jika saya ingin memberikan informasi kontekstual tambahan dalam pengecualian.
  2. Saya menggunakan uji coba umum pada titik masuk aplikasi, atau tingkat tertinggi yang mungkin. Jika pengecualian sampai di sini saya hanya mencatatnya dan membiarkannya gagal. Idealnya pengecualian tidak boleh sampai di sini.

Saya menemukan kode berikut sebagai bau:

try
{
    //do something
}
catch(Exception)
{
   throw;
}

Kode seperti ini tidak ada gunanya dan tidak boleh dimasukkan.

JoshBerke
sumber
@ Astaga, poin bagus tentang menelan pengecualian, tetapi saya yakin ada beberapa kasus di mana hanya menelan pengecualian dapat diterima. Dalam proyek terakhir cuplikan kode Anda diamanatkan, itu berbau busuk. Mencatat semuanya membuatnya menjadi lebih buruk, Saran saya, jika Anda tidak dapat menangani pengecualian, cobalah untuk tidak menelannya.
smaclell
Setuju seperti yang saya katakan, ini semua tergantung pada aplikasi dan konteks tertentu. Ada kalanya saya menelan pengecualian meskipun jarang, dan saya tidak dapat mengingat kapan terakhir kali saya melakukannya ;-) Mungkin saat itu saya sedang menulis logger saya sendiri, dan menulis ke log, dan log sekunder gagal.
JoshBerke
Kode tersebut melayani sebuah titik: Anda dapat mengatur breakpoint pada "lemparan".
Rauhotz
3
Titik lemah, Anda dapat memberi tahu VS untuk memutuskan pengecualian yang dilemparkan atau Anda dapat mempersempitnya dan memilih pengecualian tertentu. Di VS2008 ada item menu di bawah debug (Anda harus menyesuaikan bilah alat Anda untuk menemukannya) Disebut Pengecualian
JoshBerke
Contoh "code bau" memiliki efek samping yang pasti, bahkan dalam bentuk yang sederhana. Jika // do somethingmemasukkan try/finallyblok di sekitar titik yang dilempar, finallyblok akan dieksekusi sebelum catchblok. Tanpa itu try/catch, pengecualian akan terbang ke atas tumpukan tanpa ada finallyblok yang dieksekusi. Ini memungkinkan penangan tingkat atas untuk memutuskan apakah akan mengeksekusi finallyblok atau tidak .
Daniel Earwicker
9

Saya ingin merekomendasikan sumber bagus lainnya tentang topik ini. Ini adalah wawancara dengan penemu C # dan Java, masing-masing Anders Hejlsberg dan James Gosling, tentang topik Pengecualian yang Dicentang Java.

Kegagalan dan Pengecualian

Ada juga sumber daya yang bagus di bagian bawah halaman.

Saya cenderung setuju dengan Anders Hejlsberg dan Anda bahwa sebagian besar penelepon hanya peduli jika operasi berhasil atau tidak.

Bill Venners : Anda menyebutkan masalah skalabilitas dan versi sehubungan dengan pengecualian yang dicentang. Bisakah Anda menjelaskan apa yang Anda maksud dengan dua masalah tersebut?

Anders Hejlsberg : Mari kita mulai dengan pembuatan versi, karena masalahnya cukup mudah dilihat di sana. Katakanlah saya membuat metode foo yang mendeklarasikannya melontarkan pengecualian A, B, dan C. Dalam versi dua dari foo, saya ingin menambahkan banyak fitur, dan sekarang foo mungkin melempar pengecualian D. Ini adalah perubahan besar bagi saya untuk tambahkan D ke klausa lemparan dari metode itu, karena pemanggil yang ada dari metode itu hampir pasti tidak akan menangani pengecualian itu.

Menambahkan pengecualian baru ke klausa lemparan dalam versi baru akan merusak kode klien. Ini seperti menambahkan metode ke antarmuka. Setelah Anda memublikasikan antarmuka, itu untuk semua tujuan praktis tetap, karena setiap penerapannya mungkin memiliki metode yang ingin Anda tambahkan di versi berikutnya. Jadi, Anda harus membuat antarmuka baru. Demikian pula dengan pengecualian, Anda harus membuat metode baru yang disebut foo2 yang melempar lebih banyak pengecualian, atau Anda harus menangkap pengecualian D di foo baru, dan mengubah D menjadi A, B, atau C.

Bill Venners : Tapi apakah Anda tidak memecahkan kode mereka dalam kasus itu, bahkan dalam bahasa tanpa pengecualian? Jika versi baru foo akan mengeluarkan pengecualian baru yang harus dipikirkan klien tentang penanganannya, bukankah kode mereka rusak hanya karena mereka tidak mengharapkan pengecualian itu ketika mereka menulis kode?

Anders Hejlsberg : Tidak, karena dalam banyak kasus, orang tidak peduli. Mereka tidak akan menangani pengecualian ini. Ada pengendali pengecualian tingkat bawah di sekitar loop pesan mereka. Pawang itu hanya akan memunculkan dialog yang mengatakan apa yang salah dan melanjutkan. Pemrogram melindungi kode mereka dengan menulis try akhirnya ada di mana-mana, sehingga mereka akan mundur dengan benar jika terjadi pengecualian, tetapi mereka sebenarnya tidak tertarik untuk menangani pengecualian.

Klausa throws, setidaknya cara penerapannya di Java, tidak selalu memaksa Anda untuk menangani pengecualian, tetapi jika Anda tidak menanganinya, ini memaksa Anda untuk mengetahui dengan tepat pengecualian mana yang mungkin lolos. Ini mengharuskan Anda untuk menangkap pengecualian yang dinyatakan atau memasukkannya ke dalam klausa lemparan Anda sendiri. Untuk menyiasati persyaratan ini, orang melakukan hal-hal konyol. Misalnya, mereka menghiasi setiap metode dengan, "throws Exception". Itu benar-benar mengalahkan fitur tersebut, dan Anda baru saja membuat pemrogram menulis lebih banyak omong kosong. Itu tidak membantu siapa pun.

EDIT: Menambahkan detail lebih lanjut tentang percakapan

Gant
sumber
Terima kasih untuk ini! Saya memperbarui pertanyaan saya dengan info tentang jawaban Anda!
AtariPete
Sepertinya Tuan Hejlsberg membenarkan penanganan pengecualian Pokemon. Salah satu masalah besar dengan desain pengecualian di Java dan C # adalah terlalu banyak informasi yang dikodekan dalam jenis pengecualian, sementara informasi harus disimpan dalam contoh pengecualian tidak tersedia dengan cara yang konsisten. Pengecualian harus menyebarkan tumpukan panggilan sampai semua kondisi abnormal yang ditunjukkan dengan demikian telah diselesaikan; sayangnya, jenis pengecualian - meskipun dikenali - tidak banyak menunjukkan apakah suatu situasi telah diselesaikan. Jika pengecualian tidak dikenali ...
supercat
... situasinya bahkan lebih buruk. Jika kode memanggil FetchDatadan melontarkan pengecualian dari jenis yang tidak diharapkan, ia tidak memiliki cara untuk mengetahui apakah pengecualian itu hanya berarti bahwa data tidak tersedia (dalam hal ini kemampuan kode untuk bertahan tanpanya akan "menyelesaikannya"), atau apakah itu berarti CPU sedang terbakar dan sistem harus melakukan "penghentian keamanan" pada kesempatan pertama. Sepertinya Tn. Hejlsberg menyarankan bahwa kode harus mengasumsikan yang pertama; mungkin itulah strategi terbaik yang diberikan hierarki pengecualian yang ada, tetapi tetap saja tampaknya menjengkelkan.
supercat
Saya setuju bahwa lemparan Kecuali itu konyol, karena hampir semua hal dapat membuat pengecualian, Anda harus menganggap ini bisa terjadi. Tetapi ketika Anda menentukan pengecualian seperti lemparan A, B, C, itu hanya anotasi, bagi saya, itu harus digunakan seperti blok Komentar. Ini seperti mengatakan, hai klien fungsi saya, berikut tipnya, mungkin Anda ingin berurusan dengan A, B, C, karena kesalahan ini kemungkinan besar terjadi saat menggunakan saya. Jika Anda menambahkan D di masa mendatang, bukan masalah besar jika tidak ditangani, tetapi itu seperti menambahkan dokumentasi baru, Oh ya, sekarang akan berguna juga untuk menangkap D.
Didier A.
8

Pengecualian yang dicentang adalah masalah kontroversial pada umumnya, dan di Jawa pada khususnya (nanti saya akan mencoba menemukan beberapa contoh untuk mereka yang mendukung dan menentang mereka).

Sebagai aturan praktis, penanganan pengecualian harus sesuai dengan pedoman ini, tanpa urutan tertentu:

  • Demi pemeliharaan, selalu catat pengecualian sehingga ketika Anda mulai melihat bug, log akan membantu mengarahkan Anda ke tempat bug Anda kemungkinan besar dimulai. Jangan pernah meninggalkan printStackTrace()atau semacamnya, kemungkinan salah satu pengguna Anda akan mendapatkan salah satu dari pelacakan tumpukan itu pada akhirnya, dan sama sekali tidak memiliki pengetahuan tentang apa yang harus dilakukan dengannya.
  • Tangkap pengecualian yang bisa Anda tangani, dan hanya yang itu, dan tangani , jangan hanya menumpuknya.
  • Selalu menangkap kelas pengecualian tertentu, dan umumnya Anda tidak boleh menangkap tipe Exception, Anda sangat mungkin menelan pengecualian penting.
  • Tidak pernah (pernah) menangkap Error!! , artinya: Jangan pernah menangkap Throwables karena Errors adalah subkelas dari yang terakhir. Errors adalah masalah yang kemungkinan besar tidak akan pernah bisa Anda tangani (misalnya OutOfMemory, atau masalah JVM lainnya)

Mengenai kasus spesifik Anda, pastikan bahwa klien apa pun yang memanggil metode Anda akan menerima nilai pengembalian yang sesuai. Jika ada yang gagal, metode pengembalian boolean mungkin menampilkan false, tetapi pastikan tempat Anda memanggil metode tersebut dapat menanganinya.

Yuval Adam
sumber
Pengecualian yang dicentang tidak menjadi masalah di C # karena tidak memilikinya.
cletus
3
Imho, terkadang ada baiknya untuk menangkap kesalahan: Saya ingat aplikasi Java yang sangat intensif memori yang saya tulis. Saya menangkap OutOfMemory-Ex, dan menunjukkan pesan kepada pengguna bahwa dia kehabisan memori, bahwa dia harus keluar dari program lain dan memberi tahu dia cara memulai jvm dengan lebih banyak ruang heap yang ditetapkan. Saya kira itu membantu.
Lena Schimmel
5

Anda seharusnya hanya menangkap pengecualian yang dapat Anda tangani. Misalnya, jika Anda berurusan dengan membaca melalui jaringan dan waktu koneksi habis dan Anda mendapatkan pengecualian, Anda dapat mencoba lagi. Namun jika Anda membaca melalui jaringan dan mendapatkan pengecualian IndexOutOfBounds, Anda benar-benar tidak dapat mengatasinya karena Anda tidak (yah, dalam hal ini Anda tidak akan) tahu apa yang menyebabkannya. Jika Anda akan mengembalikan false atau -1 atau null, pastikan itu untuk pengecualian tertentu. Saya tidak ingin perpustakaan yang saya gunakan mengembalikan false pada jaringan yang dibaca saat pengecualian yang ditampilkan adalah heap kehabisan memori.

Malfist
sumber
3

Pengecualian adalah kesalahan yang bukan merupakan bagian dari eksekusi program normal. Bergantung pada apa yang dilakukan program Anda dan kegunaannya (yaitu pengolah kata vs. monitor jantung), Anda akan ingin melakukan hal yang berbeda saat Anda menemukan pengecualian. Saya telah bekerja dengan kode yang menggunakan pengecualian sebagai bagian dari eksekusi normal dan ini jelas merupakan kode bau.

Ex.

try
{
   sendMessage();

   if(message == success)
   {
       doStuff();
   }
   else if(message == failed)
   {
       throw;
   }
}
catch(Exception)
{
    logAndRecover();
}

Kode ini membuatku muntah. IMO Anda tidak boleh memulihkan dari pengecualian kecuali program kritis. Jika Anda melempar pengecualian maka hal-hal buruk terjadi.

Holograham
sumber
2

Semua hal di atas tampaknya masuk akal, dan seringkali tempat kerja Anda mungkin memiliki kebijakan. Di tempat kami, kami telah menetapkan jenis Pengecualian: SystemException(tidak dicentang) dan ApplicationException(dicentang).

Kami telah sepakat bahwa SystemExceptionkemungkinan besar tidak dapat dipulihkan dan akan ditangani sekali di atas. Untuk memberikan konteks lebih lanjut, kami SystemExceptions exteneded untuk menunjukkan di mana mereka terjadi, misalnya RepositoryException, ServiceEception, dll

ApplicationExceptions bisa memiliki arti bisnis seperti InsufficientFundsExceptiondan harus ditangani oleh kode klien.

Tapi sebuah contoh konkret, sulit untuk mengomentari penerapan Anda, tetapi saya tidak akan pernah menggunakan kode pengembalian, ini adalah masalah pemeliharaan. Anda mungkin menelan sebuah Pengecualian, tetapi Anda perlu memutuskan alasannya, dan selalu mencatat peristiwa dan stacktrace. Terakhir, karena metode Anda tidak memiliki pemrosesan lain, metode ini cukup mubazir (kecuali untuk enkapsulasi?), Jadi doactualStuffOnObject(p_jsonObject);dapat mengembalikan boolean!


sumber
1

Setelah beberapa pemikiran dan melihat kode Anda, menurut saya Anda hanya melemparkan kembali pengecualian sebagai boolean. Anda bisa membiarkan metode melewati pengecualian ini (Anda bahkan tidak perlu menangkapnya) dan menanganinya di pemanggil, karena di situlah hal itu penting. Jika pengecualian akan menyebabkan pemanggil untuk mencoba kembali fungsi ini, pemanggil haruslah yang menangkap pengecualian.

Kadang-kadang terjadi bahwa pengecualian yang Anda hadapi tidak masuk akal bagi pemanggil (yaitu pengecualian jaringan), dalam hal ini Anda harus menggabungkannya dalam pengecualian khusus domain.

Jika di sisi lain, pengecualian menandakan kesalahan yang tidak dapat diperbaiki dalam program Anda (yaitu hasil akhir dari pengecualian ini adalah penghentian program) Saya pribadi ingin membuatnya eksplisit dengan menangkapnya dan melemparkan pengecualian waktu proses.

wds
sumber
1

Jika Anda akan menggunakan pola kode dalam contoh Anda, beri nama TryDoSomething, dan tangkap pengecualian tertentu saja.

Pertimbangkan juga untuk menggunakan Filter Pengecualian saat membuat log pengecualian untuk tujuan diagnostik. VB memiliki dukungan bahasa untuk filter Pengecualian. Tautan ke blog Greggm memiliki implementasi yang dapat digunakan dari C #. Filter pengecualian memiliki properti yang lebih baik untuk debuggability atas tangkapan dan lempar ulang. Secara khusus, Anda dapat mencatat masalah di filter dan membiarkan pengecualian terus menyebar. Metode itu memungkinkan pelampiran debugger JIT (Just in Time) untuk memiliki tumpukan asli penuh. Pelemparan ulang memotong tumpukan pada titik lemparan ulang.

Kasus-kasus di mana TryXXXX masuk akal adalah saat Anda menggabungkan fungsi pihak ketiga yang menampilkan kasus yang tidak benar-benar luar biasa, atau yang sederhana sulit untuk diuji tanpa memanggil fungsi tersebut. Contohnya seperti ini:

// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse); 

bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
     try
     {
         parsedInt = ParseHexidecimal(numberToParse);
         return true;
     }
     catch(NumberNotHexidecimalException ex)
     {
         parsedInt = 0;
         return false;
     }
     catch(Exception ex)
     {
         // Implement the error policy for unexpected exceptions:
         // log a callstack, assert if a debugger is attached etc.
         LogRetailAssert(ex);
         // rethrow the exception
         // The downside is that a JIT debugger will have the next
         // line as the place that threw the exception, rather than
         // the original location further down the stack.
         throw;
         // A better practice is to use an exception filter here.
         // see the link to Exception Filter Inject above
         // http://code.msdn.microsoft.com/ExceptionFilterInjct
     }
}

Apakah Anda menggunakan pola seperti TryXXX atau tidak lebih merupakan pertanyaan gaya. Pertanyaan tentang menangkap semua pengecualian dan menelannya bukanlah masalah gaya. Pastikan pengecualian tak terduga diizinkan untuk disebarkan!

Steve Steiner
sumber
Saya suka pola TryXXX di .net.
JoshBerke
1

Saya sarankan mengambil isyarat Anda dari perpustakaan standar untuk bahasa yang Anda gunakan. Saya tidak bisa berbicara untuk C #, tapi mari kita lihat Java.

Misalnya java.lang.reflect.Array memiliki setmetode statis :

static void set(Object array, int index, Object value);

Cara C adalah

static int set(Object array, int index, Object value);

... dengan nilai pengembalian menjadi indikator keberhasilan. Tapi Anda tidak berada di dunia C lagi.

Setelah Anda menerima pengecualian, Anda akan menemukan bahwa itu membuat kode Anda lebih sederhana dan lebih jelas, dengan memindahkan kode penanganan kesalahan Anda dari logika inti Anda. Bertujuan untuk memiliki banyak pernyataan dalam satu tryblok.

Seperti yang telah dicatat orang lain - Anda harus sespesifik mungkin dalam jenis pengecualian yang Anda tangkap.

ramping
sumber
ini adalah komentar yang sangat valid, hormati bahasanya dan bagaimana bahasa itu secara tradisional menangani masalah semacam itu. Jangan membawa pola pikir C ke dalam dunia Java.
AtariPete
0

Jika Anda akan menemukan Exception dan mengembalikan false, itu harus menjadi pengecualian yang sangat spesifik. Anda tidak melakukan itu, Anda menangkap semuanya dan kembali salah. Jika saya mendapatkan MyCarIsOnFireException, saya ingin segera mengetahuinya! Pengecualian lainnya yang mungkin tidak saya pedulikan. Jadi Anda harus memiliki setumpuk penangan Exception yang mengatakan "whoa whoa ada sesuatu yang salah di sini" untuk beberapa pengecualian (lempar ulang, atau tangkap dan lempar ulang pengecualian baru yang menjelaskan lebih baik apa yang terjadi) dan hanya mengembalikan false untuk yang lain.

Jika ini adalah produk yang akan Anda luncurkan, Anda harus mencatat pengecualian tersebut di suatu tempat, ini akan membantu Anda menyesuaikannya di masa mendatang.

Sunting: Mengenai pertanyaan membungkus semuanya dalam coba / tangkap, saya pikir jawabannya adalah ya. Pengecualian harus sangat jarang di kode Anda sehingga kode di blok catch dieksekusi sangat jarang sehingga tidak mencapai performa sama sekali. Pengecualian harus berupa keadaan di mana mesin negara Anda rusak dan tidak tahu apa yang harus dilakukan. Setidaknya perlihatkan kembali pengecualian yang menjelaskan apa yang terjadi pada saat itu dan memiliki pengecualian yang tertangkap di dalamnya. "Pengecualian dalam metode doSomeStuff ()" tidak terlalu membantu bagi siapa pun yang harus mencari tahu mengapa perangkat rusak saat Anda sedang berlibur (atau di pekerjaan baru).

jcollum.dll
sumber
Jangan lupa bahwa pengaturan blok pengecualian juga membutuhkan biaya ...
devstuff
0

Strategi saya:

Jika fungsi asli mengembalikan batal, saya mengubahnya menjadi bool kembali . Jika terjadi pengecualian / kesalahan, kembalikan false , jika semuanya baik-baik saja, kembalikan true .

Jika fungsi harus mengembalikan sesuatu maka ketika pengecualian / kesalahan terjadi kembalikan null , jika tidak, item yang dapat dikembalikan.

Alih-alih bool sebuah string yang bisa dikembalikan yang berisi deskripsi kesalahan.

Dalam setiap kasus sebelum mengembalikan apapun mencatat kesalahan.

Badai kuman
sumber
0

Beberapa jawaban bagus di sini. Saya ingin menambahkan, bahwa jika Anda akhirnya mendapatkan sesuatu seperti yang Anda posting, setidaknya mencetak lebih dari jejak tumpukan. Katakan apa yang Anda lakukan saat itu, dan Ex. GetMessage (), untuk memberikan kesempatan kepada pengembang.

dj_segfault
sumber
saya sepenuhnya setuju. Saya hanya melakukan Ex.printStackTrace (); sebagai contoh dari sesuatu yang saya lakukan di tangkapan (yaitu tidak melempar kembali).
AtariPete
0

blok coba / tangkap membentuk rangkaian logika kedua yang disematkan di set pertama (utama), dengan demikian blok ini merupakan cara yang bagus untuk mengeluarkan kode spaghetti yang tidak terbaca dan sulit untuk di-debug.

Namun, jika digunakan secara wajar, mereka bekerja dengan sangat baik dalam keterbacaan, tetapi Anda sebaiknya mengikuti dua aturan sederhana:

  • menggunakannya (secara hemat) di tingkat rendah untuk mengetahui masalah penanganan library, dan mengalirkannya kembali ke alur logika utama. Sebagian besar penanganan error yang kita inginkan, harus berasal dari kode itu sendiri, sebagai bagian dari data itu sendiri. Mengapa membuat kondisi khusus, jika data yang dikembalikan tidak istimewa?

  • gunakan satu penangan besar di tingkat yang lebih tinggi untuk mengelola salah satu atau semua kondisi aneh yang muncul dalam kode yang tidak tertangkap di tingkat rendah. Lakukan sesuatu yang berguna dengan kesalahan (log, restart, pemulihan, dll).

Selain dua jenis penanganan kesalahan ini, semua kode lainnya di tengah harus bebas dan bebas dari kode coba / tangkap dan objek kesalahan. Dengan begitu, ia bekerja dengan sederhana dan seperti yang diharapkan di mana pun Anda menggunakannya, atau apa pun yang Anda lakukan dengannya.

Paul.

Paul W Homer
sumber
0

Saya mungkin sedikit terlambat dengan jawabannya tetapi penanganan kesalahan adalah sesuatu yang selalu dapat kami ubah dan berkembang seiring waktu. Jika Anda ingin membaca lebih banyak tentang subjek ini, saya menulis posting di blog baru saya tentang hal itu.http://taoofdevelopment.wordpress.com

Selamat membuat kode.

GRGodoi
sumber