封面:洛小汐
译者:潘潘

知彼知己,方能百战不殆。

前言

本文总结了无关Java异样的十大常见问题。

目录

  1. 查看型异样(checked) vs. 非查看型异样(Unchecked)
  2. 异样治理的最佳实际箴言
  3. 为什么在try代码块中申明的变量不能在catch或者finally中被援用?
  4. 为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?
  5. Java中常常应用的运行时异样
  6. 咱们能够在同一个catch子句中捕捉多个异样吗?
  7. 在 Java 中构造方法能抛出异样吗?
  8. 在 final 代码块中抛出异样
  9. try语句有return那么finally还会执行吗?
  10. 为何有些开发人员对异样束之高阁?

查看型异样(checked) vs. 非查看型异样(Unchecked)
简略来说,对于查看型异样, 个别在 编译期 就会被查看到,所以咱们必定会提前在办法内进行捕捉解决,或者在办法头部申明并抛出。而非查看型异样,往往无奈提前预知,例如被除数是0、空指针等。查看型异样特地重要,它会通知那些调用你的接口的开发者们,如何提前预知并解决好这些可能产生的异样。

例如,IOException就是常见的查看型异样,而 RuntimeException(运行时异样)就是非查看型异样。在浏览残余局部之前你或者能够研读这份 Java异样的层次结构图。

异样治理的最佳实际箴言

如果能够正确处理异样,则应将其捕捉并解决,否则应将其抛出。

为什么在try代码块中申明的变量不能在catch或者finally中被援用?

看上面这段代码,在try代码块中申明的 String s 就不能在catch中被援用, 这段代码在编译期是通不过的。

try {    File file = new File("path");    FileInputStream fis = new FileInputStream(file);    String s = "inside";} catch (FileNotFoundException e) {    e.printStackTrace();    System.out.println(s);}

起因是你不晓得在try代码块中哪个地位会引发异样, 很有可能在申明对象之前就引发了异样。对于这个特定的示例,是正确的。

为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?

它俩抛出的异样的确不同,但这是JDK的问题,过后开发这两个接口的开发人员不是同一波,所以咱们没必要去纠结这个问题。

Integer.parseInt(null); // throws java.lang.NumberFormatException: null Double.parseDouble(null); // throws java.lang.NullPointerException

Java中常常应用的运行时异样

这里列举一部分:

IllegalArgumentException
ArrayIndexOutOfBoundsException

在有些场景某个指标对象不满足咱们的预期,会用到这些异样,例如上面在 if 判断语句中被应用:

if (obj == null) {   throw new IllegalArgumentException("obj can not be null");

咱们能够在同一个catch子句中捕捉多个异样吗?

答案是当然能够,不过如果在同一个catch子句中捕捉的这些异样都间接或间接继承自同一父类,那么就只能在catch子句中捕捉父类了。

// Java 7 之前须要这样catch (AException a) {     logger.error(a);     throw new MyException("a");catch (BException b) {     logger.error(b);     throw new MyException("b");}catch (CException c) {     logger.error(c);     throw new MyException("c");}// 在Java 7中,能够捕捉所有这些异样 catch(AException | BException | CException ex){     logger.error(ex);     throw new MyException(ex);}
补充阐明 : 其实是这样,在 Java7 就开始反对catch子句捕捉多个异样,多个异样应用 XOR符号(I)连贯,异样的产生有可能是 A | B,但不能同时呈现,相当于这些异样不能是间接或间接继承自同一个父类,因为如果AB都继承同一父类,那就不能 A|B 都写上,这也是继承准则。

在 Java 中构造方法能抛出异样吗?

答案是当然能够,构造方法仅是一种非凡办法而已。能够参考这个示例。

在 final 代码块中抛出异样

上面这个写法是非法的:

public static void main(String[] args) {    File file1 = new File("path1");    File file2 = new File("path2");    try {         FileInputStream fis = new FileInputStream(file1);    } catch (FileNotFoundException e) {        e.printStackTrace();    } finally {        try {            FileInputStream fis = new FileInputStream(file2);        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }}

然而为了取得更好的代码可读性,你应该将把 try-catch代码块封装成一个新办法,而后将办法调用放在finally子句中:

public static void main(String[] args) {    File file1 = new File("path1");    File file2 = new File("path2");    try {         FileInputStream fis = new FileInputStream(file1);    } catch (FileNotFoundException e) {        e.printStackTrace();    } finally {        // 封装办法        methodThrowException();     }}

try语句有return那么finally还会执行吗?

答案是必定会执行。

Java官网文档形容:The finally block always executes when the try block exits

意思就是 ” 只有存在try代码块,finally代码块就肯定会执行 ” ,这种个性能够让程序员防止在try语句中应用return, continue或者break关键字而疏忽了敞开相干资源的操作等。

为何有些开发人员对异样束之高阁?

很多时候会见到上面这种代码写法。容许的状况下尽可能捕捉异样并且进行解决,不晓得为什么很多开发人员就是这么干?

try {     ...} catch(Exception e) {     e.printStackTrace();}

疏忽异样是一件很容易做到的事,尽管这种写法很常见,但不肯定是正确的写法。

参考文献:
  1. Unchecked exceptions in Java
  2. The root of Java exception class hierarchy
  3. Java exceptions related questions in stackoverflow
译文完,因为集体理解能力和常识宽度无限,译文中存在失误之处,还请见谅,欢送斧正。

BIU ~ 文章继续更新,微信搜寻「潘潘和他的敌人们」第一工夫浏览,随时有惊喜。本文会在 GitHub https://github.com/JavaWorld 收录,热腾腾的技术、框架、面经、解决方案,咱们都会以最美的姿态第一工夫送达,欢送 Star。