最常见的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. 为何有些开发人员对异常置之不理?

1.检查型异常(checked) vs 非检查型异常(Unchecked)

简单来说,对于检查型异常, 一般在 编译期 就会被检查到,所以我们肯定会提前在方法内进行捕获处理,或者在方法头部申明并抛出。而非检查型异常,往往无法提前预知,例如被除数是0、空指针等。检查型异常特别重要,它会告诉那些调用你的接口的开发者们,如何提前预知并处理好这些可能发生的异常。

例如,IOException就是常见的检查型异常,而 RuntimeException(运行时异常)就是非检查型异常。在阅读剩余部分之前你或许可以研读这份Java异常的层次结构图。

2.异常管理的最佳实践箴言

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

3. 为什么在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代码块中哪个位置会引发异常, 很有可能在声明对象之前就引发了异常。对于这个特定的示例,是正确的。

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

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

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

5.Java中经常使用的运行时异常

这里列举一部分:

IllegalArgumentException ArrayIndexOutOfBoundsException

在有些场景某个目标对象不满足我们的预期,会用到这些异常,例如下面在 if 判断语句中被使用:

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

6.我们可以在同一个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 都写上,这也是继承原则。

7.在 Java 中构造方法能抛出异常吗?

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

class FileReader{public FileInputStream fis = null;public FileReader() throws IOException{File dir = new File(".");//get current directoryFile fin = new File(dir.getCanonicalPath() + File.separator + "not-existing-file.txt");fis = new FileInputStream(fin);}
}

8.在 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(); }
}

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

答案是肯定会执行。

Java官方文档描述:The finally block always executes when the try block exits

意思就是 ” 只要存在try代码块,finally代码块就一定会执行 ” ,这种特性可以让程序员避免在try语句中使用return, continue或者break关键字而忽略了关闭相关资源的操作等。

10.为何有些开发人员对异常置之不理?

很多时候会见到下面这种代码写法。允许的情况下尽可能捕获异常并且进行处理,不知道为什么很多开发人员就是这么干?

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

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


往期推荐

SpringBoot接口幂等性实现的4种方案!


try-catch-finally中的4个巨坑,老程序员也搞不定!


对象复制的7种方法,还是Spring的最好用!


关注我,每天陪你进步一点点!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OSSIM学习-英汉对照注释

Ossim的Web UI目前没有很好的本地化解决方案,这给不少初学Ossim的用户尤其是英文不太好的人来说,带来了一些麻烦,下面是部分英汉对照注释,并在不断完善中,希望对大家学习过程中,有所帮助。Action 动作Actio…

Cookie的设置获取和删除

关于Cookie操作的实验&#xff0c;包括设置&#xff0c;获取和删除。 设置Cookie name[必选]value[必选]expiredays[必选]setCookie getCookie 操作Cookie GETDEL 以下是源代码&#xff1a; <html><head><meta charset"utf-8" /><script type&q…

observable_Java Observable clearChanged()方法与示例

observable可观察的类clearChanged()方法 (Observable Class clearChanged() method) clearChanged() method is available in java.util package. clearChanged()方法在java.util包中可用。 clearChanged() method represents that this object has no longer changed or in o…

Linux中Samba详细安装

为了实现Windows主机与Linux服务器之间的资源共享&#xff0c;Linux操作系统提供了Samba服务&#xff0c;Samba服务为两种不同的操作系统架起了一座桥梁&#xff0c;使Linux系统和Windows系统之间能够实现互相通信&#xff0c;为广泛的Linux爱好者提供了极大方便。本文简要介绍…

Java ObjectInputStream close()方法与示例

ObjectInputStream类close()方法 (ObjectInputStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close this ObjectInputStream and free any system resources linked with this str…

Java获取文件类型的5种方法

前言工作中经常会用到&#xff0c;判断一个文件的文件类型&#xff0c;这里总结一把&#xff0c;一般判断文件类型的原理有2种方式&#xff1a;根据文件扩展名判断优点&#xff1a;速度快&#xff0c;代码简单缺点&#xff1a;无法判断出真实的文件类型&#xff0c;例如一些伪造…

OpenCart 之 CSV 格式商品导入 – 如何导入商品主图片和附加图片?

1. 在文件中定义多个附加图片可以为一个商品导入多个图片。这些图片需要以“附加图片分隔符”来分割&#xff0c;而附加图片分隔符的定义在扩充功能配置页面。下面是一个带有URL链接的多个图片的填写格式&#xff1a;…,”http://www.example.com/p_w_picpath1.png:::http://ww…

你以为用了BigDecimal后,计算结果就一定精确了?

BigDecimal&#xff0c;相信对于很多人来说都不陌生&#xff0c;很多人都知道他的用法&#xff0c;这是一种java.math包中提供的一种可以用来进行精确运算的类型。很多人都知道&#xff0c;在进行金额表示、金额计算等场景&#xff0c;不能使用double、float等类型&#xff0c;…

tohexstring方法_Java Float类toHexString()方法的示例

tohexstring方法浮动类toHexString()方法 (Float class toHexString() method) toHexString() method is available in java.lang package. toHexString()方法在java.lang包中可用。 toHexString() method is used to represent a hexadecimal string of the given parameter […

Google 开源的依赖注入库,比 Spring 更小更快!

来源 | zhuanlan.zhihu.com/p/24924391Guice是Google开源的一个依赖注入类库&#xff0c;相比于Spring IoC来说更小更快。Elasticsearch大量使用了Guice&#xff0c;本文简单的介绍下Guice的基本概念和使用方式。学习目标概述&#xff1a;了解Guice是什么&#xff0c;有什么特点…

Servlet页面跳转实现方法的区别

Servlet页面跳转实现方法的区别 http://developer.51cto.com/art/200907/133803.htm本文向您介绍Servlet页面跳转实现方法的几种区别&#xff0c;包括Servlet和JSP中的不同实现&#xff0c;比如Servlet中的redirect方式和forward方式得区别等。一直对Servlet页面跳转的几种方式…

Java Double类shortValue()方法与示例

双类shortValue()方法 (Double class shortValue() method) shortValue() method is available in java.lang package. shortValue()方法在java.lang包中可用。 shortValue() method is used to return the value denoted by this Double object converted to type short (by c…

这个 bug 让我更加理解 Spring 单例了

谁还没在 Spring 里栽过跟头呢&#xff0c;从哪儿跌倒&#xff0c;就从哪儿睡一会儿&#xff0c;然后再爬起来。讲点儿武德 这是由一个真实的 bug 引起的&#xff0c;bug 产生的原因就是忽略了 Spring Bean 的单例模式。来&#xff0c;先看一段简单的代码。public class TestS…

mysql优化--叶金荣老师讲座笔记

copy to tmp table执行ALTER TABLE修改表结构时建议&#xff1a;凌晨执行Copying to tmp table拷贝数据到内存中的临时表&#xff0c;常见于GROUP BY操作时建议&#xff1a;创建索引Copying to tmp table on disk临时结果集太大&#xff0c;内存中放不下&#xff0c;需要将内存…

JS判断文本框中只能输入数字和小数点

http://liva-zheng.iteye.com/blog/1733827 1.文本框只能输入数字(不包括小数点) <input οnkeyup"this.valuethis.value.replace(/\D/g,)" onafterpaste"this.valuethis.value.replace(/\D/g,)"> 2.只能输入数字和小数点. <input οn…

java 方法 示例_Java集合asLifoQueue()方法和示例

java 方法 示例集合类asLifoQueue()方法 (Collections Class asLifoQueue() method) asLifoQueue() Method is available in java.lang package. asLifoQueue()方法在java.lang包中可用。 asLifoQueue() Method is used to represent the given deque as a Lifo queue (LIFO me…

废弃fastjson!大型项目迁移Gson保姆级实战

前言本篇文章是我这一个多月来帮助组内废弃fastjson框架的总结&#xff0c;我们将大部分Java仓库从fastjson迁移至了Gson。这么做的主要的原因是公司受够了fastjson频繁的安全漏洞问题&#xff0c;每一次出现漏洞都要推一次全公司的fastjson强制版本升级&#xff0c;很令公司头…

网页如何做到适应在手机上浏览

http://bbs.php100.com/read-htm-tid-482066.html 目前有很多不错的mobile开发框架可以使用&#xff0c;这些框架已经为手机端的特殊性提供了很好的支持和效果插件&#xff0c;比如&#xff1a;jquery mobile、kendoui等~~ 不过&#xff0c;谢谢框架因为其开源性或商业化&…

学到了!MySQL 8 新增的「隐藏索引」真不错

MySQL 8.0 虽然发布很久了&#xff0c;但可能大家都停留在 5.7.x&#xff0c;甚至更老&#xff0c;其实 MySQL 8.0 新增了许多重磅新特性&#xff0c;比如栈长今天要介绍的 "隐藏索引" 或者 "不可见索引"。隐藏索引是什么鬼&#xff1f; 隐藏索引 字面意思…

Java ClassLoader findLibrary()方法与示例

ClassLoader类findLibrary()方法 (ClassLoader Class findLibrary() method) findLibrary() method is available in java.lang package. findLibrary()方法在java.lang包中可用。 findLibrary() method is used to find the absolute pathname of the given native library. f…