赞
踩
在java应用中,异常的处理机制分为声明异常,抛出异常和捕获异常。
通常,应该捕获那些知道如何处理的异常,将不知道如何处理的异常继续传递下去。传递异常可以在方法签名处使用throws关键字声明可能会抛出的异常。
注意
如果你觉得解决不了某些异常问题,且不需要调用者处理,那么你可以抛出异常。
throw关键字作用是在方法内部抛出一个Throwable类型的异常。任何Java代码都可以通过throw语句抛出异常。
程序通常在运行之前不报错,但是运行后可能会出现某些未知的错误,但是还不想直接抛出到上一级,那么就需要通过try…catch…的形式进行异常捕获,之后根据不同的异常情贺来进行相应的处理。
可以根据下图来选择是捕获异常,声明异常还是抛出异常
通常,应该捕获那些知道如何处理的异常,将不知道如何处理的异常继续传递下去。传递异常可以在方法签名处使用throws关键字声明可能会抛出的异常。
private static void readFile(String filepath) throws IoException{
File file=new File(filePath);
String result;
BufferedReader reader=new BufferedReader(new FileReader(file));
while((result=reader. readLine())!=nul1){
system. out. print1n(result);
reader. close();
}
有时我们会从catch中抛出一个异常,目的是为了改变异常的类型。多用于在系统集成时,当某个子系统故障,异常类型可能有多种,可以用统一的异常类型向外霸露,不需暴露太多内部异常细节。
private static void readFile(String filePath) throws MyException{
try{
//code
}catch(IOException e){
MyException ex=new MyException("read file failed.");
ex.initCause(e);
throw ex;
}
}
在一个try-catch语句块中可以捕获多个异常类型,并对不同类型的异常做出不同的处理
private static void readFile(String filepath){
try{
//code
}catch(FileNotFoundException e){
//handte FileNotFoundException
}catch(IOException e){
//handLe IOException
}
}
同一个catch也可以捕获多种类型异常,用|隔开
private static void readFile(String filePath){
try{
//code
}catch(FileNotFoundException|UnknownHostException e){
//handte FileNotFoundException or UnknownHostException
}catch(IOException e){
//handle IOException
}
}
习惯上,定义一个异常类应包含两个构造函数,一个无参构造函数和一个带有详细描述信息的构造函数(Throwable的toString方法会打印这些详细信息,调试时很有用)
public class MyException extends Exception{
public MyException(){}
public MyException(String msg){
super(msg);
}
//...
}
当方法中发生异常,异常处之后的代码不会再执行,如果之前获取了一些本地资源需要释放,则需要在方法正常结束时和catch语句中都调用释放本地资源的代码,显得代码比较繁琐,finally 语句可以解决这个问题。
private static void readFile(String filepath) throws MyException{ File file=new File(filePath); string result; BufferedReader reader=nul1; try{ reader=new BufferedReader(new FileReader(file)); while((result=reader. readLine())!=nul1){ system. out. println(result); } } catch(IoExceptione){ system. out. println("readFile method catch block."); MyException ex=new MyException("read file failed."); ex. initCause(e); throw ex; } finally{ system. out. println("readFile method finally block."); if(null != reader){ try{ reader. close(); } catch(IOException e){ e. printstackTrace(); } } }
调用该方法时,读取文件时若发生异常,代码会进入catch代码块,之后进入finally代码块;若读取文件时未发生异常,则会跳过catch代码块直接进入finally代码块。所以无论代码中是否发生异常,fianlly中的代码都会执行。
若catch代码块中包含return 语句,finally中的代码还会执行吗?将以上代码中的catch子句修改如下:
catch(IOException e){
System. out. printin("readFile method catch block.");
return;
}
调用readFile方法,观察当catch子句中调用return 语句时,finally子句是否执行
readFile method catch block.
readFile method finally block.
可见,即使catch中包含了return语句,finally子句依然会执行。若finally中也包含return语句,finally中的return会覆盖前面的return.
上面例子中,finally中的close方法也可能抛出I0Exception,从而覆盖了原始异常。JAVA
7提供了更优雅的方式来实现资源的自动释放,自动释放的资源需要是实现了AutoCloseable接口的类。
private static void tryWithResourceTest(){
try(Scanner scanner = new Scanner(new FileInputStream("c:/abc"),"UTF-8")){
//code
}catch(IOException e){
//handle exception
}
}
try代码块退出时,会白动调用scanner.close方法,和把scanner.close方法放在finally代码块中不同的是,若scanner.close抛出异常,则会被抑制,抛出的仍然为原始异常。被抑制的异常会由addSusppressed方法添加到原来的异常,如果想要获取被抑制的异常列表,可以调用getSuppressed方法来获取。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。