(一)概述
java相关的异常和错误,都是由Throwable派生出来的。
Throwable之下,有两大类,Error和Exception。
(二)错误和异常
Error(错误): 基本都是程序无法处理的问题。大多数情况下是基于jvm运行时发生的问题,如OutOfMemoryError
等。
此类错误并不是明确的某块程序代码上的错误。需要结合系统的运行来做整体的分析。
如内存溢出,应该分析是哪些地方的逻辑有误,或者访问量太大而导致内存不够等,再结合实际以确定解决方案。并不是简单地修改问题代码就能解决的问题。
Exception(异常): 主要分为checked
异常、unchecked
异常。是程序本身可以处理和防范的异常。
(三)Exception异常
checked异常:
- 程序编译时报出的异常,不解决不给编译通过。一般是从你已经写出的代码中(如调用获取文件的方法),程序已经检查到可能出现的异常(获取文件的方法,程序已经定义好了其异常),必须在代码中显示地处理(
try-catch
、throws
) - 表示无效,不是程序中可以预测的。比如无效的用户输入,文件不存在,网络或者数据库链接错误。这些都是外在的原因,都不是程序内部可以控制的。
- 必须在代码中显式地处理。比如
try-catch
块处理,或者给所在的方法加上throws说明,将异常抛到调用栈的上一层。 - 继承自
java.lang.Exception
(java.lang.RuntimeException
除外)。
unchecked异常:
- 程序编译通过,实际运行时报出的异常。比如:
a=1,b=0;c=a/b;
在编译时不会报错,但实际运行时会报出异常。因为程序在编译时,不会检查具体的值,所以按照程序逻辑,没有问题。但是在实际运行时,代入了实际值,运算就报错了。 - 表示错误,程序的逻辑错误。是
RuntimeException
的子类,比如IllegalArgumentException,NullPointerException
和IllegalStateException
等。 - 不需要在代码中显式地捕获unchecked异常做处理。
- 继承自j
ava.lang.RuntimeException
(而java.lang.RuntimeException
继承自java.lang.Exception
)。
Java异常之所以会分为这两种,大致是出于如下考虑:
checked异常可以帮助开发人员意识到哪一行有可能会出现异常,因为Java的API已经说明了调用哪些方法可能会抛出异常。如果不做处理编译就不能通过,从某种程度上说,这种做法可以避免程序的一些错误。