1

Что лучше между несколькими блоками catch и Exception? К лучше, я имею в виду по хорошему методу.Несколько блоков блокировки «ChildException» versius один блок блокировки «Исключение»

Для иллюстрации:

public static void main(String[] args) { 
    System.out.println(Main.isNonsense1(null)); // false <- bad 
    System.out.println(Main.isNonsense2(null)); // NullPointerException <- good 
} 

// More readable, less precise 
public static boolean isNonsense1(String className) { 
    try { 
     Class.forName(className); 
     String.class.getConstructor(String.class); 
     className.getBytes("UTF-8"); 
     MessageDigest.getInstance("SHA-1").wait(); 
     return true; 
    } catch (Exception e) { 
     return false; 
    } 
} 

// Less readable, more precise 
public static boolean isNonsense2(String className) { 
    try { 
     Class.forName(className); 
     String.class.getConstructor(String.class); 
     className.getBytes("UTF-8"); 
     MessageDigest.getInstance("SHA-1").wait(); 
     return true; 
    } catch (ClassNotFoundException e) { 
     return false; 
    } catch (NoSuchMethodException e) { 
     return false; 
    } catch (SecurityException e) { 
     return false; 
    } catch (UnsupportedEncodingException e) { 
     return false; 
    } catch (NoSuchAlgorithmException e) { 
     return false; 
    } catch (InterruptedException e) { 
     return false; 
    } 
} 
+0

Если все, что вы хотите, должно вернуть false, то не беспокойтесь, чтобы специализироваться на случаях. – ron

ответ

4

Это связано с этим вопрос: Catch multiple exceptions at once?

Ответ там хороший. Ключ в том, что если вы поймаете Exception, тогда вы должны обработать каждый из случаев, о которых вы знаете, и throw все остальное. То есть просто ловить Exception в вашем примере и вернуть false будет не - хорошая идея. Вы можете случайно поймать какое-то исключение, о котором вы не хотели.

Используя ваш пример, вот мой Рекомендованный код:

public static boolean isNonsense2(String className) { 
    try { 
     Class.forName(className); 
     String.class.getConstructor(String.class); 
     className.getBytes("UTF-8"); 
     MessageDigest.getInstance("SHA-1").wait(); 
     return true; 
    } catch (Exception e) { 
     if (e instanceof ClassNotFoundException 
       || e instanceof NoSuchMethodException 
       || e instanceof SecurityException 
       || e instanceof UnsupportedEncodingException 
       || e instanceof NoSuchAlgorithmException 
       || e instanceof InterruptedException) { 
      return false; 
     } else { 
      throw e; 
     } 
    } 
} 
+0

Спасибо, хорошая идея использовать 'instanceof', кстати':) ' – sp00m

+0

Я также должен предупредить, что одним из недостатков этого сделать является то, что компилятор больше не будет предупреждать вас, если вы обрабатываете ** проверенное исключение ** который не может быть брошен кодом в блоке 'try'. – Luke

1

Я думаю, что нет полного однозначного ответа. В вашем случае я бы закодировать его так:

public static boolean isNonsense1(String className) { 
    if(slassname==null) throw new IllegalArgumentException("className must not be null"); 
    try { 
     Class.forName(className); 
     String.class.getConstructor(String.class); 
     className.getBytes("UTF-8"); 
     MessageDigest.getInstance("SHA-1").wait(); 
     return true; 
    } catch (ClassNotFoundException e) { 
     throw new IllegalArgumentException("provided class " + className + " not found"); 
    } catch (Exception e) { 
     return false; 
    } 
} 

На мой вкус, метании NullPointerException всегда плохо, вот почему я бросаю IllegalArgumentException

0

Если вы не заинтересованы в обработке исключений (который вы должны в соответствии с наилучшей практикой), не заморачиваться с явными уловами. Весь смысл иметь возможность обрабатывать определенные исключения - это позволить вам правильно обрабатывать их.