Java7新特性--实战篇(五)

2014-11-24 09:01:34 · 作者: · 浏览: 3
// class java/io/FileReader
7: dup
8: ldc #4 // String
10: invokespecial #5 // Method java/io/FileReader."":(Ljava/lang/String;)V
13: invokespecial #6 // Method java/io/BufferedReader."":(Ljava/io/Reader;)V
16: astore_0
17: aconst_null
18: astore_1
19: aload_1
20: invokeinterface #7, 1 // InterfaceMethod java/sql/Connection.createStatement:()Ljava/sql/Statement;
25: astore_2
26: goto 34
29: astore_0
30: aload_0
31: invokevirtual #10 // Method java/lang/Exception.printStackTrace:()V
34: return
Exception table:
from to target type
0 26 29 Class java/io/IOException
0 26 29 Class java/sql/SQLException


使用两个catch生成的字节码

[java]
public static void second();
Code:
0: new #2 // class java/io/BufferedReader
3: dup
4: new #3 // class java/io/FileReader
7: dup
8: ldc #4 // String
10: invokespecial #5 // Method java/io/FileReader."":(Ljava/lang/String;)V
13: invokespecial #6 // Method java/io/BufferedReader."":(Ljava/io/Reader;)V
16: astore_0
17: aconst_null
18: astore_1
19: aload_1
20: invokeinterface #7, 1 // InterfaceMethod java/sql/Connection.createStatement:()Ljava/sql/Statement;
25: astore_2
26: goto 42
29: astore_0
30: aload_0
31: invokevirtual #11 // Method java/io/IOException.printStackTrace:()V
34: goto 42
37: astore_0
38: aload_0
39: invokevirtual #12 // Method java/sql/SQLException.printStackTrace:()V
42: return
Exception table:
from to target type
0 26 29 Class java/io/IOException
0 26 37 Class java/sql/SQLException


switch那里生成的字节码不太明显看出来优化在哪里,这个很明显。首先,字节码长度变少 其次,从最后可以看出,target type都指向29行,两个catch会指向不同的行~

2、用更包容性的类型检查来重新抛出异常

在方法的声明上,使用throws语句时,你可以指定更加详细的异常类型。


[java]
static class FirstException extends Exception { }
static class SecondException extends Exception { }

public void rethrowException(String exceptionName) throws Exception {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e;
}
}


这个例子,try块中只能抛出两种异常,但是因为catch里的类型是 Exception,在java SE7以前的版本中,在方法声明中throws 只能写Exception,但是在java SE7及以后的版本中,可以在throws后面写 FirstException和SecondException——编译器能判断出throw e语句抛出的异常一定来自try块,并且try块只能抛出FirstException和SecondException。

[java]
public static void reThrowException(String exceptionName)
throws FirstException, SecondException{
try {
if ("first".equals(exceptionName))
throw new FirstException();
else
throw new SecondException();
} catch (Exception e) {
throw e;
}
}


所以尽管catch里的异常类型是Exception,编译器仍然能够知道它是FirstException和 SecondException的实例。怎么样,编译器变得更智能了吧。

但是,如果在catch里对异常重新赋值了,在方法的throws后无法再向上面那样写成FirstException和SecondExcep