整体架构如下:
多重捕捉,可以catch多个异常,异常之间不得有继承关系,否则会发生编译错误。
先举个例子展示throw和throws的使用方法,示例代码如下,示例代码的主要功能是读取文件中的文字内容并转化为一个String对象。throw用于方法体中,通常为catch的程序块,但不限于catch,任何位置使用throw抛出异常,会直接跳离当前流程。throws用于声明方法后抛出受检异常。
public static String readFile(String fileName) throws Exception{
StringBuffer text = new StringBuffer();
try{
Scanner console = new Scanner(new FileInputStream(fileName));
while (console.hasNextInt()){
text.append(console.nextLine()).append("\n");
}
}catch (FileNotFoundException ex){
//日志记录等其他操作
throw ex;
}
return text.toString();
}
注意,如果使用throw抛出受检异常E,则其所在的函数必须使用throws关键字抛出E或E的父类异常。对于非受检异常,编译程序不强制要求函数使用throws。
在继承中,父类throws多个异常,子类重新定义该方法时
那什么时候该抓,什么时候该抛?以下给我我所理解的该抛出的情况
异常这里有很多理论描述都比较拗口,也很难理解。我们在设计程序可以通过继承来自定义受检异常和非受检异常。那么如何在受检异常和非受检异常进行选择?我们需要考虑,调用方是否在调用时可以处理这种异常,如果其无力处理,必须提前做好前置条件再调用,那么就应该选择非受检异常。书里举了一个我不知道的例子,这里记录一下,留个印象Hibernate2中的HibernateException为受检异常,但Hibernate3中就变成了非受检异常。
e.fillInStackTrace()方法:可以重新装填异常堆栈,将起点设置为重新抛出异常的地方。书中的示例代码如下
static void a(){
try{
b();
} catch (NullPointerException ex){
System.out.println("抛出a异常");
ex.printStackTrace();
Throwable throwable = ex.fillInStackTrace();
throw (NullPointerException)throwable;
}
}
static void b(){
c();
}
static void c(){
String text = null;
text.toUpperCase();
}
public static void main(String[] args){
try {
a();
}catch (Exception e){
System.out.println("抛出main异常");
e.printStackTrace();
}
}
输出结果如下,可以看出通过函数a的处理,重新组装异常,main抛出的异常的起点位置为重新抛出异常的地方(a).
断言——“assert”就像是由编译程序控制是否能够执行的if语句。语法如下,若boolean_expression为false则发生java.lang.AssertionError,如果采取第二个语法,会将detail_expression的结果显示出来,如果detail_expression是个对象则会调用此对象的toString()方法。
assert boolean_expression;
assert boolean_expression: detail_expression;
为什么说是由编译程序控制的呢?如果我们在执行java指令时,指定-enableassertions或者-ea就会启动断言指令,否则不执行,编译程序就会忽略这段代码。
1、try模块无论有误异常,finally都会执行,如果try/catch中return了,会先执行finally的语句再返回。
2、自动关闭资源(Try-With-Resources),语法及示例如下,将打开资源的代码放到try后面的括号中,即使不用撰写专门的finally去关闭资源,改资源也能自动调用类的close方法被自动关闭。这是jdk7之后的程序蜜糖,通过反编译程序可以看出来,是编译程序自动将其编译成了finally语句。与一般的try相比,自动关闭资源可以不撰写catch语句,但是如果没有catch语句抓住异常,必须由其所在的函数将对应异常抛出。
public static String readFile(String fileName) throws FileNotFoundException{
StringBuffer text = new StringBuffer();
try(Scanner console = new Scanner(new FileInputStream(fileName))){
while (console.hasNextInt()){
text.append(console.nextLine()).append("\n");
}
}
return text.toString();
}
如果有多个资源语句,它们之间使用分号“;”隔开,关闭时由后至前调用close方法关闭。
3、可以关闭资源(包括自动关闭资源)的对象都继承了java.lang.AutoCloseable,必须实现接口的close方法。
若一个异常被catch后的处理过程引发另一个异常,通常会抛出第一个异常作为相应。第二个异常通过addSuppressed()方法记录在第一个异常中,再通过getSuppressed()方法获得之前被add进去的第二个Thowable对象。该方法再jdk7后才增加的。
自动关闭资源,虽然使用try,但由于不强制其使用catch,所以可以将它和捕获异常分开来看。try后的程序块可以没有异常,那么其所在的函数也就可以不用throws任何异常。