Mengapa hindari menggunakan pengecualian untuk mengontrol aliran Anda di Java

Java adalah bahasa pemrograman universal yang memiliki banyak solusi alternatif untuk tugas spesifik Anda. Namun demikian, ada beberapa pendekatan yang baik yang harus diikuti, dan ada juga beberapa pendekatan yang gagal yang sebagian besar masih kita gunakan.

Salah satu pendekatan gagal yang paling umum adalah menggunakan pengecualian untuk mengontrol alur eksekusi. Ini harus dihindari karena dua alasan:

  1. Ini mengurangi kinerja dan kecepatan kode Anda.
  2. Ini membuat kode Anda kurang mudah dibaca.

Mari kita mulai dengan melihat sebuah contoh. Di sini pengecualian digunakan untuk mengontrol aliran eksekusi:

public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if(name==null) { throw new NameNotFoundException(); } return name; } 

Jika pengguna memberikan nilai non-null untuk nama, maka metode findAge akan mengembalikan panjang nama ini, tetapi jika nama pengguna adalah null, maka metode findUser akan melempar pengecualian NameNotFoundException dan dalam kasus ini metode findAge akan mengembalikan 0.

Bagaimana kami bisa mengonversi kode ini tanpa menggunakan pengecualian? Secara umum, ada banyak opsi, pertimbangkan salah satunya:

 public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if(name==null) { return ""; } return name; } 

Untuk mengetahui dampak pengecualian terhadap kinerja, saya menyiapkan kode berikut yang menyebut kedua varian metode ini 10 juta kali: dengan dan tanpa pengecualian.

 public class ControlFlowWithExceptionOrNot { public static class NameNotFoundException extends RuntimeException { private static final long serialVersionUID = 3L; } private static final int TRIAL = 10000000; public static void main(String[] args) throws InterruptedException { long start = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAgeNoEx(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start)); long start2 = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAge(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start2)); }; public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if (name == null) { throw new NameNotFoundException(); } return name; } public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if (name == null) { return ""; } return name; } } 

Kesimpulan:

 Duration :16 Duration :6212 

Seperti yang Anda lihat, menggunakan pengecualian menghabiskan ribuan milidetik pada Intel Core i7-3630QM saya.

Jika kita membandingkan dua metode findAge kita dalam hal keterbacaan, metode tanpa kecuali benar-benar jelas: pertama, kita dapat benar-benar yakin bahwa metode findUser mengembalikan string; dan kedua, terlepas dari string mana yang akan dikembalikan, kami mendapatkan panjangnya. Pada saat yang sama, metode dengan pengecualian agak membingungkan: tidak sepenuhnya jelas apa yang dikembalikan oleh metode findUser. Itu bisa mengembalikan string, atau bisa melempar pengecualian dan ini tidak terlihat dari tanda tangan metode. Karena alasan ini, paradigma pemrograman fungsional tidak menyambut baik penggunaan pengecualian.

Pada akhirnya, akan lebih baik jika Anda menggunakan pengecualian di mana pengecualian benar-benar muncul dan diperlukan. Jika Anda menggunakan pengecualian untuk mengontrol alur eksekusi, ini akan menyebabkan penurunan kinerja program dan membuat kode Anda kurang terbaca.

Saya harap artikel ini menarik bagi Anda, dan mungkin bermanfaat.

Source: https://habr.com/ru/post/id476142/


All Articles