Java异常

简介: 总结了一些Java异常知识点。

在我参与过的一些Java项目、或者阅读过Java代码中,异常的使用或多或少都有点问题,有些甚至是误用。可能很多人都了解异常的基本知识,但是使用的时候往往过于随意,然而这样的随意往往并不能造成什么严重的问题,所以很多程序员,尤其是初级的程序员也就没有在意它,于是代码中总是会有那些让人不舒服的异常使用代码;另一方面,Java异常类型中包括Checked Exception(Runtime Exception)和Unchecked Exception,这两中异常的使用也颇具争议。
基于上述问题,总结一下Java异常基本知识点及常见错误,错漏之处欢迎批评指正。

异常的基本思想:首先是抛出异常,然后catch捕捉,但是catch得和try连用(try也可以仅和finally连用,无需catch的参与),catch捕捉的是try区中代码抛出的异常,一个 try可以跟多个catch,每个catch捕捉一种类型的异常,不确定异常时可用异常的super类,exception。异常的捕捉顺序按照catch的先后顺序。

1、Java异常结构

这里写图片描述

所有的Java异常都是继承自Throwable。Throwable分为Error和Exception两大类,而程序员需要关注的是Exception这一部分的异常,Error不需要应用程序编程人员来使用的,按照《Java核心技术卷1》的定义:

Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误,应用程序不应该抛出这样的错误。

显然一旦这样的错误出现,程序除了终止别无他法。

2、Unchecked and Checked Exception

Error和Runtime Exception合称为Unchecked Exception,对应的另一类异常叫做Checked Exception。它们的区别在于后者编译时会被check,Java语言要求程序员必须捕获这样的异常(Checked Exception)或者沿着调用栈向上抛出,即在有可能抛出异常的方法体对应的方法名后加上throws specified-exception(例如throws exception)。常见的Checked异常包括IOException,例如用户的输入不符合要求、程序打开一个不存在的文件等。
另一类异常,Runtime Exception(Unchecked Exception),Java官方认为这样的异常其实是bug,这类异常应该是去解决而不是去捕获,所以Java不要求程序员捕获这类异常,但是程序员仍然可以去捕获这类的异常,这类异常包括空指针、数组访问越界等。
初学者可能会误认为文件读写异常或者用户输入异常是RuntimeException,其实不然,这里提醒一下。

3、自定义异常选择:Unchecked vs Checked

自定义异常选用Unchecked还是checked类型的一直以来就充满争议,而且其它语言也都只有RuntimeException,如C++。当然这些争议只存在于Java使用者之中,Java官方并不存在任何争议。
因为Java语言要求程序员必须捕获Checked Exception,于是很多程序员为了偷“不需要主动捕获异常”这个懒(当然也有很多程序员是出于设计的原因),将所有的自定义异常都继承自RuntimeException,这样就可以“想捕获就捕获,不想捕获就随它去了”。
我个人的观点是:遵循Java规范。原因有二:其一,定义Checked异常可以最大限度地借助IDE工具帮助我们规范代码,同时规范的代码也能告诉其他的代码调用者这段代码会抛出什么样的异常,也许有人会说,RuntimeException也可以在方法体上声明抛出何种异常,但是这样就不能最大限度的利用IDE或者编译器了,人总会有疲劳的时候,能让工具干的事情我们就不要插手了;其二,Java使用者甚多,遵循Java规范可能是唯一能让整个Java世界编程风格统一的方式了。

4、一个可能是Java编程史上最常见的异常使用错误

try {
    some codes;
}catch(Exception e){// 上来就直接使用异常的super类-Exception,可能程序并不会抛出任何异常或者仅仅是一个IOException
    some codes;
}

与其说是错误,不如说是使用不规范。(有没有随口而出,“我擦,我每天都是这么用的”)

5、异常小知识

1、捕获那些知道如何处理的异常,而将那些不知道如何处理的异常继续向上传递。
2、如果这是你编程造成的问题,那就是RuntimeException,反之亦然。
3、try不一定要与catch连用,也可以只接finally;但是try必须与catch或者finally中的一个或者全部一起使用。
4、finally块中尽可能地不要写return语句。
5、如果try块中有return语句,finally块会在try块的return语句return之前执行(假定try能执行到return语句)。
6、catch中捕获异常的顺序应遵循子类先catch的原则。

目录
相关文章
|
1月前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
59 1
|
1月前
|
Java API 调度
如何避免 Java 中的 TimeoutException 异常
在Java中,`TimeoutException`通常发生在执行操作超过预设时间时。要避免此异常,可以优化代码逻辑,减少不必要的等待;合理设置超时时间,确保其足够完成正常操作;使用异步处理或线程池管理任务,提高程序响应性。
62 12
|
1月前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
34 1
|
1月前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
66 7
|
1月前
|
Java 编译器
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
70 6
|
1月前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
64 1
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
60 2
|
1月前
|
Java
如何在 Java 中处理“Broken Pipe”异常
在Java中处理“Broken Pipe”异常,通常发生在网络通信中,如Socket编程时。该异常表示写入操作的另一端已关闭连接。解决方法包括:检查网络连接、设置超时、使用try-catch捕获异常并进行重试或关闭资源。
104 5
|
1月前
|
存储 安全 Java
如何避免 Java 中的“ArrayStoreException”异常
在Java中,ArrayStoreException异常通常发生在尝试将不兼容的对象存储到泛型数组中时。为了避免这种异常,确保在操作数组时遵循以下几点:1. 使用泛型确保类型安全;2. 避免生类型(raw types)的使用;3. 在添加元素前进行类型检查。通过这些方法,可以有效防止 ArrayStoreException 的发生。
41 3
|
2月前
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
43 2
下一篇
DataWorks