如果程序出现错误使得某些操作没有完成,程序应该:返回一种安全状态,让用户执行一些其他的命令或者允许用户保存操作结果,并以适当的方式终止程序。
异常处理的任务就是将控制权从错误产生的地方移交给能够处理这种情况的处理器。
在Java中,如果某个方法不能采取正常的途径完成它的任务,就可以通过:方法不返回任何值,立刻退出(调用这个方法的代码也无法继续执行),抛出throw一个封装了错误信息的对象,异常处理机制开始搜索能够处理这种异常的处理器。
异常对象都派生于Throwable类,Throwable又立刻分成两部分,Error和Exception.
Error:描述Java运行时系统内部错误和资源耗尽错误,但是程序不应该抛出这种类型的对象。如果出现了这种错误,除了告知用户,尽力使程序安全地终止外别无他法。
Exception:又分为RuntimeException(程序错误)和IOException(程序本身没问题、其他错误,比如IO)
RuntimeException:错误的类型转换、数组越界、访问空指针(一定是程序员的问题)
非RuntimeException:试图在文件尾部后面读取数据,打开一个不存在的文件,根据字符串查找一个并不存在的Class对象
Error+RuntimeException=未检查异常
不需要抛出从Error继承的错误,无能为力
也不需要声明从RuntimeException继承的那些未检查异常,因为这类错误完全在我们的控制之下
其他:已检查异常(编译器将核查是否为所有 已检查异常提供了异常处理器)
一个方法不仅要告诉编译器返回什么值,还有可能发生什么错误,例如读取文件的代码要告知可能发生IOException异常
一个方法必须声明所有可能抛出的已检查异常,而Error不可控制,RuntimeException避免发生
继承中的异常抛出:
子类方法中声明的已检查异常要比超类中的更具体
如果超类方法没有抛出任何已检查异常,子类也不能抛出任何已检查异常
超类方法可以不声明抛出的异常
对于一个确定的异常类,比如IO读取错误:创建这个类的对象,将对象抛出:throw new IOException()。。。。也需要在最前面声明throws IOException
没有任何标准异常能充分描述的问题:创建异常类以同样的方式throw
调用的函数抛出异常,可以选择自己捕获catch,也可以继续抛出,
捕获异常
try{
}catch (ExceptionType e){
}
在try语句块中任何代码抛出了异常,,并且有匹配的catch捕获,那么程序将跳过try剩余的语句,执行catch
如果try没有抛出异常,catch不执行
try {
InputStream i=new FileInputStream("asd");//操作是会向外抛出异常,必须throws或者catch
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
如果这里异常被catch到,可以接着执行后面的操作,但要是也throws,没有处理就不行了
如果发生了异常,没有自己catch而是向外抛,则自己后续的代码无法继续执行(不管外部有没有catch处理)
处理知道怎么办的异常,向外抛出无能为力的异常
finally语句
当代码抛出一个异常,就会终止剩余代码的执行(包括try中,异常后面的剩余部分),并退出该方法的执行
不管异常是否被捕获,finally都会被执行,
try{
//1
抛出异常
//2
}catch(Exception){
//3
打印异常信息
//4
}finally{
//5
}
//6
1:没有抛出异常,则1、2、5、6
2:抛出一个在catch能捕获的异常:假设catch没有抛出异常,则1、3、4、5、6
3:抛出异常,catch不能捕获:1、5 (后面的无法再执行了,要将异常抛给方法的调用者)
当try和finally都包含return:在执行try的return前会执行finally,然后finally会先把自己的东西return
public static int aa(){
try{
System.out.println(1);
return 1;
}finally{
System.out.println(2);
return 2;//覆盖了try的return
}
}
如果try本来要抛出异常A,结果finally也排除了异常B,则A也被覆盖,要处理这个问题需要两层try、finally
对于使用资源的try,如果finally负责关闭资源,可以使用Java7的新方法,
对于实现了AutoCloseable接口的类,
try(Resource res=。。。)//res=new Scanner(new FileInputStream(“......”))
{
//使用资源
}
try正常退出或者遇到异常都会自动进行res.close()就和执行了finally一样,但资源close抛出的异常会被抑制,并自动捕获并添加到原来的异常中
只要是需要关闭资源,尽量这样处理