关于java:译文最常见的10种Java异常问题

封面:洛小汐
译者:潘潘

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

前言

本文总结了无关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。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理