异常
概念与分类
-
所谓异常或错误,就是程序的运行发生了问题,这时 Java 会构造出一个异常或错误对象,并抛出。
-
在 Java 中,
Throwable
类是所有错误和异常的超类,继承体系如下:-
错误
Error
:- 一般是程序运行时系统、JVM 等发生的严重问题,一般并不需要考虑在程序代码里对其进行捕获
catch
处理(特殊情况下,想捕获处理它也行)。
如:
- 内存空间不足错误:
java.lang.OutOfMemoryError
- 方法调用栈溢出错误:
java.lang.StackOverFlowError
- ……
- 一般是程序运行时系统、JVM 等发生的严重问题,一般并不需要考虑在程序代码里对其进行捕获
-
异常
Exception
:-
运行时异常
RuntimeException
:-
若运行程序的时候系统抛出运行时异常,则一定是代码本身存在错误,要根据控制台输出的异常错误提示信息修改代码即可,而不需要在程序代码中对其进行捕获
catch
处理; -
对于运行时异常,Java 不强制要求用异常处理机制进行捕获
catch
处理(自己要处理也行),在编译的时候也不会对其进行检查。
如:
- 算术运算异常:
java.lang.ArithmeticException
- 数组索引越界异常:
java.lang.ArrayIndexOutOfBoundsException
- 空指针异常:
java.lang.NullPointerException
- ……
-
-
非运行时异常:
- 非运行时异常一般是在应用环境中出现的外部错误,并不是代码本身的错误,这种外部的不确定性,我们需要对此准备好问题发生后的处理方案;
- 对于非运行时异常,Java 也会强制要求要对其用异常处理机制进行捕获
catch
处理,以保证程序运行时若碰到这样的问题还能继续正常运行。在编译时,也会对此进行检查。
如:
- IO异常:
java.io.IOException
- SQL异常:
java.sql.SQLException
- ……
-
-
-
简单地从 Java 编译器层面来说:
Error
和RuntimeException
及其子类称为不检查异常,编译器不对它们进行异常处理方面的语法检查;- 其它的异常,也就是非运行时异常,称为受检查异常,编译器会对它们进行语法检查,在代码上,要么用
try...catch...
,在本层进行捕获处理;要么在本层方法中暂不处理,把异常向上throws
,让上层调用者考虑处理的事情。
异常处理
-
抛出异常的方式:
-
手动抛出异常:
使用语句
throw new XXX();
,其中,XXX extends ... extends Throwable
在方法体中使用
throw
抛出可查异常(非运行时异常)时,需要在对应的方法名处用throws
声明出其可能抛出的异常的类型。 -
自动抛出异常:
若程序的运行发生了问题,则 JVM 会自动构造出一个相应的异常或错误对象并在发生问题的地方抛出,效果与上等价。
-
-
异常对象被抛出后的执行机制:
-
程序会立刻放弃对
throw
语句后续语句的执行,并在本层或向上层寻找能捕获此异常对象的catch
块,找到则执行,找不到就继续向上抛 …… -
所谓“能捕获”,是指异常对象的类型和
catch
声明的括号内参数类型相匹配。-
若异常对象最终被主程序
main()
方法抛出,则整个程序终止运行; -
多线程的情况下,若某个线程的异常对象最终被
Thread.run()
抛出,则该线程终止运行;(此条学完多线程再看一下说的准不准确)
-
-
-
try...catch...
语法:try { ... } catch (XXX x) { ... }
或
try { ... } catch (XXX x) { ... } finally { ... }
说明:
- 不管是否有异常产生,
finally
块中代码都会执行; - 当
try
和catch
中有return
语句时,finally
块仍然会执行; finally
是在return
后面的表达式运算后执行的,所以函数返回值是在finally
执行前确定的。无论finally
中的代码怎么样,返回的值都不会改变,仍然是之前return
语句中保存的值;finally
中最好不要包含return
,否则程序会提前退出,返回值不是try
或catch
中保存的返回值。
- 不管是否有异常产生,
-
使用自定义异常:
-
Throwable
的成员方法:方法名 说明 public String getMessage() 返回此Throwable对象的详细消息 public String toString() 返回此可抛出的简短描述 public void printStackTrace() 把异常的错误信息输出在控制台 -
要自定义一个异常,让它继承
Exception
类 或者Throwable
类,再提供适当的构造方法即可,注意catch
的括号内声明的参数类型要能捕获它。
-