工学1号馆

home

java核心系列13-异常处理

By Wu Yudong on June 13, 2015

原创文章,转载请注明: 转载自工学1号馆

在这篇文章将系统的剖析java中的异常的机制和应用

异常分类

可以看到,Exception类是所有异常的基类,由程序错误导致的异常都属于RuntimeException,所以“如果出现RuntimeException异常,一定是你的问题”

声明已检查的异常

在自己写方法的时候,什么时候需要在方法中用throws子句声明异常,什么异常必须使用throws子句声明,遇到下面的四种情况的时候应该抛出异常:

1、调用一个抛出已检查异常的方法,例如:

public FileInputStream(String name) throws FileNotFoundException

2、程序运行过程中发现错误,并利用throw语句抛出一个已检查异常

3、程序出错误

4、java虚拟机和运行库出现内部错误

对于那些可能被他人使用的java方法,应该按照异常规范,在方法的首部声明这个方法可能抛出的异常

class test {
    //...
    public Image loadImage(String s) throws IOException {
        //...
    }
}

如果抛出多个异常,直接在方法后面继续添加异常,用逗号隔开

class test {
    //...
    public Image loadImage(String s) throws IOException , EOFException{
        //...
    }
}

注意:子类中覆盖父类的一个方法,子类中声明的已检查的异常不能比父类方法中声明的异常更加的通用,如果父类中没有抛出任何已检查的异常,那么子类也不能抛出任何已检查的异常

如何抛出异常

首先是决定应该抛出什么类型的异常,对于一个已经存在的异常类,将其抛出非常容易:

1)找到一个合适的异常类

2)常见这个类的一个对象

3)将对象抛出

看个例子:

String readData(Scanner in) throws EOFException {
    //...
    while(...) {
        if(!in.hasNext()) {
            if(n < len)
                throw new EOFException();
        }
    //...
    }
    return s;
}

创建异常类

如果任何标准库中的异常类都不能满足要求,就需要自己创建异常类。我们需要做的就是创建一个继承Exception类或其子类的类,看下面的例子:

class FileFormatException extends IOException {
	public FileFormatException(){}
	public FileFormatException(String gripe) {
		super(gripe);
	}
}
String readData(BufferedReader in) throws FileFormatException {
	//...
	while(...) {
		if(ch == -1) { //遇到EOF
			if(n < len)
				throw new FileFormatException();
		}
	//...		
	}
	return s;
}

捕获异常

要想捕获一个异常,必须设置try/catch块,最简单的示例如下:

try {
    code
    morecode
} catch (ExceptionType e) {
    handler for this type
}

如果在try中抛出一个在catch中说明的异常类,那么:

1、程序将跳过try语句块的剩余代码

2、程序将执行catch中的处理代码

如果在try中没有抛出任何异常,那么程序将跳过catch子句

如果在try中抛出一个在catch中没有说明的异常类,那么这个方法将立刻退出

finally子句

如果在方法中获得了一些本地资源,并且这些资源在退出之前需要回收,这时候需要使用finally子句

InputStream in =  new FileInputStream();
try {
	//1
	Code that may throw Exception
	//2
} catch (IOException e) {
	//3
	show error message
	//4
} finally {
	//5
	in.close();
}
//6

无论try语句块中是否遇到异常,finally子句中的in.close()语句都会被执行

强烈建议独立使用try/catch 和try/finally语句块,这样可以提高代码的清晰度,例如:

InputStream in =  new FileInputStream();
try {
	try {
		Code that may throw Exception
	} finally {
		in.close();
	}
} catch (IOException e) {
	show error message
}

内层try只有一个职责:关闭输入流,外层try也只有一个职责:确保报告出现

使用异常机制的技巧

1、异常处理不能替代简单的测试

2、不要过分地细分异常

3、利用异常层次结构

4、不要压制异常

5、在检测错误时,“苛刻”要比放任好

6、不要羞于传递异常

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)