目录
一.处理错误
二.捕获异常
  1.try-catch语法
  2.finally子句
  3.堆栈轨迹 Trace Stack
三.使用异常机制的技巧
四.断言

一.处理错误

在我们写程序的时候可能会遇到各种各样的错误:
有的是因为代码写错了, 比如逻辑错了, 语法错了, 数组越界了, 死循环了(这些不能异常处理, 只能自己好好debug改一改哈哈)等等原因;
也可能是因为其他原因比如我希望在某个地方打开一个文档, 但是该路径下并没有这个文件, 或者没有权限打开这个文件;
也有可能是我想调用网络, 但是没有网络访问权限;
Java可以使用throws来抛出异常, 所有的异常类都派生自Throwable类, 其有两个子类是Error和Exception;
Java基础 自学讲义 4. 异常 断言和日志
Error 类层次结构描述了 Java 运行时系统的内部错误和资源耗尽错误。这个比较无奈, 一般情况下不能这样瞎搞, 如果实在没办法, 那抛出异常也并没有卵用了, 只能及时终止程序, 所以这种情况要尽量避免;
在设计 Java 程序时, 需要关注 Exception 层次结构。 这个层次结构又分解为两个分支: 一个分支派生于RuntimeException; 另一个分支包含其他异常。划分两个分支的规则是:由 程序错误导致的异常属于RuntimeException; 而程序本身没有问题,但由于像I/O错误这类 问题导致的异常属于其他异常, 比如IOException;

如果希望在某个方法提示可能出现的异常, 可以在方法的大括号前面加上throws + 预期可能会出现的异常, 比如 throws IOException, 当然也可以这样表示接受所有异常:

public static void main(String[] args) throws Exception{
	//***code***
}

Java提供了一些标准的异常, 比如下面这些, 随便列了一些不全 ?
Java基础 自学讲义 4. 异常 断言和日志
但是错误的种类千奇百怪 ? ?
所以java支持自定义派生于Exception类的子类----自己的异常类:
比如下面我自己定义的FileFormatException异常:

import java.io.*;

class test11 {
	public static void main(String[] args) throws FileFormatException {
		boolean isExceptionOccur = true;
		if(isExceptionOccur) throw new FileFormatException();
	}
}

class FileFormatException extends IOException{
	public FileFormatException(){}
	public FileFormatException(String gripe){
		super(gripe);
	}
}

要注意, 如果想在程序中使用throws xxException这样的语句, 一定要在当前的方法后面加上throws xxException

二.捕获异常

1.try-catch语法

可以使用try-catch语法来捕获异常, 异常发生后将不会执行异常部位后面的代码, 直接进入catch代码块, 可以使用多个的catch语法;

		try {
			/*code*/
		} 
		catch (Exception e1) {
			/*code*/
		}
		catch (Exception e2) {
			/*code*/
		}
		catch (Exception e3) {
			/*code*/
		}

还可以使用再次抛出异常和异常链:

try {
			System.out.println(a[10]);
		} catch (Exception e) {
			throw new FileFormatException();
		}

Java基础 自学讲义 4. 异常 断言和日志
Java基础 自学讲义 4. 异常 断言和日志

2.finally子句

可以使用finally子句用于关闭某些输入流或者资源, 使用close()方法,
Java基础 自学讲义 4. 异常 断言和日志
这里有一点需要注意的地方是, finally语句是无论如何都会进入执行的, 如果程序没有任何异常, 那么会在执行完try内的语句后执行finally, 如果程序出现了异常, 那么会在执行完catch语句的内容后执行finally, 就算程序在try的语句中已经return了也会继续执行finally中的语句, 会覆盖return的内容, 比如在下面的例子中:

class test11 {
	public static void main(String[] args) throws Exception {
		System.out.println(f(3));//输出结果为0 而不是9
	}
	public static int f(int x){
		try {
			return x*x;
		} catch (Exception e) {
			
		}
		finally {
			return 0;
		}
	}
}

当然如果使用了System.exit(0);那就会直接退出不执行finally中的语句了;

3.堆栈轨迹 Trace Stack

使用getStackTrace方法, 它会得到StackTraceElement对象的一个数组, 可以在你的程序中分析这个对象数组:
Java基础 自学讲义 4. 异常 断言和日志

三.使用异常机制的技巧

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

执行简单测试花费的时间比捕获异常少很多

使用异常的基本原则:只在异常情况下使用异常机制

2.不要过分的细化异常

每条语句都封装在独立的try语句块中,将导致代码量的急剧膨胀

3.利用异常层次结构

1.不要只抛出IOException,应该寻找更加适合的自子类或者创建自己的异常类
2.不要只捕获Throwable,否则,会使程序代码更难读、更难维护
3.考虑已检查异常和未检查异常的区别
4.将一种异常转换为另一种更合适的异常时不要犹豫

4.不要压制异常

编译器会对所有调用这个方法的方法进行异常处理的考虑,如果认为异常非常重要,就应该对它们进行处理

	try{
    	code that threatens to throw checked exceptions 
	}
	catch(Exception e){
	
	}

这段代码可以通过编译,除非发生异常,否则它将可以正常运行,即使发生了异常也会被忽略

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

例如,当栈为空时,在出错的地方抛出一个EmptyStackException比在后面抛出一个NullPointerException更好

6.不要羞于传递异常

传递异常比捕获异常更好,让高层次的方法通知用户发生了错误,或者放弃不成功的命令更合适

规则5、6归纳为“早抛出,晚捕获”

四.断言

相关文章: