3.8 JAVA异常处理
![](https://p-blog.csdn.net/images/p_blog_csdn_net/summer0214/EntryImages/20090116/异常类的继承关系.gif)
异常是程序执行时遇到的任何错误情况或意外行为。
1、程序运行中,用户输入错误,磁盘满了,打印机打印中缺纸等等都会引起错误!
2、JAVA的异常处理的语句为:try-catch-finally,在这个语句中catch语句可以有一个或多个,finally语句可以省略.但是 try语句后至少要有一个catch语句或finally语句.JAVA异常处理机制只能处理Throwable类或其子类对象,所以自定义异常类层次需要选取Throwable类或其某个子类作为父类。
Throwable包括两个分支Error和Exception。
Exception包括两个大类,IOException和RuntimeException。
java语言规范将派生于RuntimeException或Error的所有异常称之为未检查异常(unchecked exception),其他异常为(checked exception)
JAVA对不同的异常类采取不同的处理策略:
- Error意味着是很难恢复的严重错误,一般不由程序处理。
- RuntimeException意味着程序设计或实现问题,例如数组使用越界,算术运算异常(例如除0运算),空指针异常(即访问没有初始化的指针)等.正确设计与实现的程序不应该产生这些异常,处理的策略是纠正错误.
注意:RuntimeException异常不是必须被catch,即使Throw了也不必catch.- 3 其他的异常通常是由环境因素引起的,如文件不存在,无效URL等.这类是由用户的误操作引起的,可以在异常处理中处理,例如,提示用户进行正确操作.
Error,Exception以及RuntimeException的区别.
- Error表示非常严重的、不可预期的异常情况,通常应用程序无需捕获并处理。
- Exception通常是一种设计或实现的异常,它是编译器可以“感知”的异常,所以程序被要求必须捕获并处理这些异常。
- RuntimeException与Error一样,也是无需捕获的,且就算在方法上throws了RuntimeException,调用该方法的语句也无需catch这些异常。就是说在声明语句returnType methodName([paramlist])throws exceptionlist中声明的异常,Exception一定要被处理,而RuntimeException异常则可以不被处理.
有些只有一个异常
java.util.TreeSet类(jdk1.5)中
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {
// Write out any hidden stuff
s.defaultWriteObject();
// Write out Comparator
s.writeObject(m.comparator());
// Write out size
s.writeInt(m.size());
// Write out all elements in the proper order.
for (Iterator i=m.keySet().iterator(); i.hasNext(); )
s.writeObject(i.next());
}
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {
// Write out any hidden stuff
s.defaultWriteObject();
// Write out Comparator
s.writeObject(m.comparator());
// Write out size
s.writeInt(m.size());
// Write out all elements in the proper order.
for (Iterator i=m.keySet().iterator(); i.hasNext(); )
s.writeObject(i.next());
}
如果有多个异常,中间用","分隔开来
java.util.TreeSet类(jdk1.5)中
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden stuff
s.defaultReadObject();
// Read in Comparator
Comparator<E> c = (Comparator<E>) s.readObject();
// Create backing TreeMap and keySet view
TreeMap tm;
if (c==null)
tm = new TreeMap();
else
tm = new TreeMap(c);
m = tm;
keySet = m.keySet();
// Read in size
int size = s.readInt();
tm.readTreeSet(size, s, PRESENT);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden stuff
s.defaultReadObject();
// Read in Comparator
Comparator<E> c = (Comparator<E>) s.readObject();
// Create backing TreeMap and keySet view
TreeMap tm;
if (c==null)
tm = new TreeMap();
else
tm = new TreeMap(c);
m = tm;
keySet = m.keySet();
// Read in size
int size = s.readInt();
tm.readTreeSet(size, s, PRESENT);
}
创建自己的异常类
public class MyAppException extends Exception {
public MyAppException() {
super();
}
public MyAppException(String message) {
super(message);
}
public MyAppException(String message, Throwable cause) {
super(message, cause);
}
public MyAppException(Throwable cause) {
super(cause);
}
}
public MyAppException() {
super();
}
public MyAppException(String message) {
super(message);
}
public MyAppException(String message, Throwable cause) {
super(message, cause);
}
public MyAppException(Throwable cause) {
super(cause);
}
}
抛出异常
if(getProjectCount(projectId,conn) < 0){
throw MyAppException("没有编号为"+projectId+"的工程");
}
throw MyAppException("没有编号为"+projectId+"的工程");
}
捕获异常
捕获一个异常
try{
do sth;
}
catch (Exception e){
handler for e;
}
捕获多个异常
try{
do sth;
}
catch (PatternSyntaxException pse){
handler for pse;
}
catch (NullPointerException npe){
handler for npe;
}
catch (Exception e){
handler for e;
}
描述更普遍的错误应该在后面
try{
do sth;
}
catch (Exception e){
handler for e;
}
捕获多个异常
try{
do sth;
}
catch (PatternSyntaxException pse){
handler for pse;
}
catch (NullPointerException npe){
handler for npe;
}
catch (Exception e){
handler for e;
}
描述更普遍的错误应该在后面
再次抛出
try{
do sth;
}
catch (Exception e){
throw MyAppException("没有编号为"+projectId+"的工程",e);
}
可以保存异常的原因,必要的时候可以把已检查异常封装为运行时异常。
do sth;
}
catch (Exception e){
throw MyAppException("没有编号为"+projectId+"的工程",e);
}
可以保存异常的原因,必要的时候可以把已检查异常封装为运行时异常。
finally子句
finally不管是否有异常都会执行,是回收资源的最好方法。
Graphics g = image.getGraphics();
try{
//1
code that might throw exception;
//2
}
catch (Exception e){
//3
show e;
//4
}
finally {
//5
g.dispose();
}
//6
情况一:代码没有抛出异常,将执行,1,2,5,6
情况二:抛出一个catch子句的异常并且catch子句没有出现异常,执行 1,3,4,5,6
情况三:抛出一个catch子句的异常并且catch子句出现异常,执行 1,3,5
情况四:抛出异常没有被catch捕获,执行1,5
需要注意的是finally中的句子不应该出现错误,当出现错误后将使原始异常丢失!!!
Graphics g = image.getGraphics();
try{
//1
code that might throw exception;
//2
}
catch (Exception e){
//3
show e;
//4
}
finally {
//5
g.dispose();
}
//6
情况一:代码没有抛出异常,将执行,1,2,5,6
情况二:抛出一个catch子句的异常并且catch子句没有出现异常,执行 1,3,4,5,6
情况三:抛出一个catch子句的异常并且catch子句出现异常,执行 1,3,5
情况四:抛出异常没有被catch捕获,执行1,5
需要注意的是finally中的句子不应该出现错误,当出现错误后将使原始异常丢失!!!