〇、为什么有异常?
我们在学习编程语言的时候,总是会假设我们有一个完全听话的使用者,他们不会做些程序没有考虑到的操作,如给整型变量一个字符,向满员的数组内继续添加数据等。然而,现实世界是不完美的,不了解代码,或是不知道程序运行机制的用户会经常做出我们无法预料的行为,
异常类型:
非检查型异常:Error, RuntimeException
其中,Error的出现表示着Java内部系统出现了错误,这种情况你除了通知用户没有更多的处理方式了
而Runtime Exception(运行时异常)包括:
强制转换错误
数组越界 - ArrayIndexOutOfBoundsException
访问null指针 - NullPointerException
没错,如果你的程序自己出现了Runtime Exception,那造成这种结果的罪魁祸首绝对是你自己,而不是用户,更不是java系统。
检查型异常(checked Exception)
不包括Runtime Exception的有:
试图在文件末尾之后继续读取数据
试图打开不存在的文件
试图根据字符串查找一个对象,然而该字符串代表的对象并不存在。
以上异常可以通过try-catch来将他尽可能地处理掉。
一、标注
方法首部标注 throws Exception1, Exception2,...
用来声明这个方法可能会抛出一个检查型异常,通过这个声明,调用该方法的上层方法只有两个选择:
1.处理掉这个异常
2.声明自己也可能抛出异常,把这个异常再向上抛出。
throws exception有时候并不是照顾的面面俱到,当你声明了一个模糊的异常类型时throws Exception,编译器会检查你的上层是否处理了确切的Exception类或者再次抛出了他,但是如果你声明了一个子类异常throws ArithmeticException,而你的上层catch了另一个无关的异常,编译器不会报错,但很显然这样会出问题。
目前认为throws在提供可读性和可维护性方面的作用大于其实际意义。
二、尝试、处理
完整格式:
try{
}
catch (Exception1 e){
}
catch (Exception2 e){
}
finally{
}
使用规范:
顺序不得改变
三者任意一条都不得单独声明
catch和finally都不得离开try进行声明
运行原理:
顾名思义,首先尝试运行try中的代码,如果抛出异常,即刻停止执行try,开始调用catch,找到匹配的异常类型,处理异常,处理完毕后执行finally
如果已经出现了try和catch,在语法层面上,由于异常已经处理完毕,不需要再继续声明后续出现的代码区域是否为finally
三、使用方法抛出异常
1、直接对某条件进行判断并使用throw new Exception() 来抛出异常,在上层使用try-catch来处理它,类似try区块,一旦一个方法抛出了自己无法处理的异常,该方法会立刻停止执行后续的代码。
2、没有catch的try-finally型:
无法处理自身抛出的异常,但他无论是否发生异常都有必须要做的事情,则将这段代码置入finally。
四、catch出现的顺序
如果你将父类异常的catch放在子类异常的tach之前,仔细想想,如果后者满足抛出的异常的类型,则前者必定也满足,因此这样的排序会导致后续的catch报废。实际上编译器根本不允许你这么做。
规范:
catch接收的异常类型不得是位于自己之前的catch所接收的异常的子类
五、处理原则
1、当你抓到了异常,务必做些什么让用户知道,不要让他淹没在运行环境里
2。当你希望抓取异常的时候,将try尽可能多地对代码进行覆盖,不要总是只测试一两行语句
3、遇到了你无法处理的异常,就不要捕获他了,你可以把它扔给更高层的方法,或是走投无路的时候直接告诉用户“你的弱智操作给我整不会了”。总之,有些时候,错不在你,请尽力而为。