封面:洛小汐

译者:潘潘

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

前言

本文总结了有关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异常的层次结构图[1]

异常管理的最佳实践箴言

如果可以正确处理异常,则应将其捕获并处理,否则应将其抛出。

为什么在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 中构造方法能抛出异常吗?

答案是当然可以,构造方法仅是一种特殊方法而已。可以参考这个文章示例[2]

在 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] Java异常的层次结构图: https://www.programcreek.com/2009/02/diagram-for-hierarchy-of-exception-classes/[2] 示例: https://www.programcreek.com/2013/01/constructor-can-throw-exceptions-in-java/[3] Unchecked exceptions in Java: https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html[4] The root of Java exception class hierarchy: https://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html[5] Java exceptions related questions in stackoverflow: https://stackoverflow.com/questions/tagged/java+exception

译文完,由于个人理解能力和知识宽度有限,译文中存在失误之处,还请见谅,欢迎指正。

java常见异常_译文最常见的10种Java异常问题相关推荐

  1. numberformatexception是什么异常_译文《最常见的10种Java异常问题》

    封面:洛小汐 译者:潘潘 知彼知己,方能百战不殆. 前言 本文总结了有关Java异常的十大常见问题. 目录 检查型异常(checked) vs. 非检查型异常(Unchecked) 异常管理的最佳实践 ...

  2. java各种的不好_译文《最常见的10种Java异常问题》

    封面:洛小汐 译者:潘潘 知彼知己,方能百战不殆. 前言 本文总结了有关Java异常的十大常见问题. 目录 检查型异常(checked) vs. 非检查型异常(Unchecked) 异常管理的最佳实践 ...

  3. 最常见的10种Java异常问题!

    封面:洛小汐 译者:潘潘 前言 本文总结了有关Java异常的十大常见问题. 目录 检查型异常(checked) vs. 非检查型异常(Unchecked) 异常管理的最佳实践箴言 为什么在try代码块 ...

  4. java oom分析_作为测试你应该知道的JAVA OOM及定位分析

    上周现网一个内存溢出问题导致应用服务器每隔一小时死一次,遂整理下常见的OMM.发现方法和处理方式,加入Bug预防. 常见的OutOfMemoryError有三种:OutOfMemoryError:Pe ...

  5. java框架核心技术_你必须掌握的 21 个 Java 核心技术!(干货)

    点击上方"java进阶架构师",选择右上角"置顶公众号" 20大进阶架构专题每日送达 51闲来无事,师长一向不(没)喜(有)欢(钱)凑热闹,倒不如趁着这时候复盘 ...

  6. c++ 外部组件发生异常_谁再悄咪咪的吃掉异常,我上去就是一 JIO

    又到周末了,周更选手申请出站~ 这图太魔性了啊 这次分享一下上个月碰到的离奇的问题.一个简单的问题,硬是因为异常被悄咪咪吃掉,过关难度直线提升,导致小黑哥排查一个晚上. 这个美好的晚上,本想着开两把 ...

  7. java转换为c#_将25k行C#转换为Java的经验教训

    java转换为c# 由于各种原因,我最近完成了一个将复杂的财务应用程序从C#转换为Java的项目. 港口的原因大部分是非技术性的,而是对相关企业的一项战略举措. 这是一次有趣的经历,我在此过程中吸取了 ...

  8. java盒图_《》——8幅图图解Java机制

    String对象不可改变的特性 String s = "abcd"; s = s.concat"ef"; equals()与hashCode()方法协作约定 H ...

  9. java future用法_你必须掌握的 21 个 Java 核心技术

    作者:工程师-搁浅来源:https://www.jb51.net/article/122070.htm 写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,主要是和一些java基础知 ...

  10. java 核型技术_你必须掌握的 21 个 Java 核心技术!(转自Java技术栈)

    写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,希望可以给大家一些经验,能让大家更好学习和使用Java. 这次介绍的主要内容是和J2SE相关的部分,另外,会在以后再介绍些J2EE ...

最新文章

  1. 程序员:如何成为一个全栈的工程师?
  2. 实模式切换到保护模式,为什么要开启A20地址线(系统升级产生的兼容性问题)
  3. Java工作笔记-WebService使用JDK搭建WebService及调用
  4. python迭代计算_Python递归和迭代
  5. python开发讲解_Python开发系列课程(1) - 初识Python详解
  6. leetcode 203 python3
  7. 发货通知单不允许新增,只能关联生成
  8. Pa2 函数指针 指针函数 分析 (转)
  9. 【洛谷P4219】【BJOI2014】—大融合(线段树合并)
  10. [Leetcode] longest common prefix 最长共同前缀
  11. Apache OpenOffice-java调用时的问题总结
  12. IDEA 删除本地文件时,SVN服务器上文件无法删除解决办法
  13. 【前端】一步一步使用webpack+react+scss脚手架重构项目
  14. POJ - 3258 River Hopscotch 二分
  15. 计算机显示器模糊,显示器模糊,我来教您电脑显示器模糊怎么办
  16. 语音识别之Fbank特征提取工具的比较(kaldi、python_speech_features、torchaudio)
  17. JS获取特殊字符前面的字符串
  18. 小白也学得会!Python编程超简单方法算圆周率
  19. Bolzano-Weierstrass 定理
  20. centos7.4安装docker

热门文章

  1. 【报错】Error inserting GREEM=30 YELLOW=4 RED=5 android.database.sqlite.SQLiteException: no such tab
  2. 【基础】位与运算与取余
  3. windows环境中JDK环境变量配置
  4. 傲娇Android二三事之诡诡异异的图片加载
  5. H3C nat转换实验
  6. 游戏开发之.h、.c、.hpp及.cpp的区别
  7. 游戏筑基开发之字符串的注意点(C语言)
  8. KVM详解(二)——KVM安装部署
  9. LNMP详解(二)——Nginx源码安装与启动
  10. 【大数据】Hbase如何批量删除指定数据