1.捕获异常:
要捕获一个异常,必须设置try/catch语句块
例如:
try{
}catch(ExceptionType e){
}
如果方法中的任何代码抛出一个在catch字句中没有声明的异常类型,那么这个方法就会立刻退出
通常,应该捕获那些知道如何处理的异常,而将那些不知道怎么处理的异常继续传递
2.捕获多个异常:
例如:
try{
}catch(FileNotFoundException e){
}catch(UnknownHostException e){
}catch(IOException e){
}
异常对象可能包含与异常本身相关的信息。要想获得对象的更多信息,可以试着使用
e.getMessage()得到详细的错误信息
e.getClass().getName()得到异常对象的实际类型
在Java SE 7中,同一个catch字句中可以捕获多个异常类型,例如:
try{
}catch(FileNotFoundException | UnknownHostException e){
}
只有当捕获的异常类型彼此之间不存在子类关系时才需要这个特性
3.再次抛出异常与异常链:
例如:
try{
}catch(SQLException e){
throw new ServletException("database error:"+e.getMessage());
}
还有一种更好的处理方法,并且将原始异常设置为新异常的“原因”
try{
}catch(SQLException e){
Throwable se = new ServletException("database error");
se.initCause(e);
throw se;
}
当捕获到异常时,就可以使用下面这条语句重新得到原始异常:
Throwable s = se.getCause();
再来看一个小细节:
public void updateRecord() throws SQLException{
...
try{
}catch(Exception e){
logger.log(level,message,e);
throw e;
}
}
在Java SE 7之前,Java编译器查看catch块中的throw语句,然后查看e的类型,会指出这个方法可以抛出任何Exception而不只是SQLException。现在这个问题有所改进。编译器会跟踪到e来自try块。假设这个try块中仅有的已检查异常是SQLException实例,另外,假设e在catch块中未改变,将外围方法声明为throws SQLException就是合法的
4.finally子句:
不管是否有异常被捕获,finally子句中的代码都被执行
try语句可以只有finally子句,而没有catch子句
当finally子句也包含return语句时,将会出现一种意想不到的结果。假设利用return语句从try语句块中退出。在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return语句,这个返回值将会覆盖原来的返回值
当finally子句本身抛出异常时,原始的异常将会丢失,转而抛出close方法的异常,如果用之前的模式进行处理就会比较繁琐,也就是需要在finally子句中再写try-catch语句,这个时候就需要下面的写法。
5.带资源的try语句:
假设资源属于一个实现了AutoCloseable接口的方法的类Java SE 7为这种代码模式提供了一个很有用的快捷方式。AutoCloseable接口有一个方法:
void close() throws Exception
另外还有一个Closeable接口,是AutoCloseable接口的子接口,也包含一个close方法,但是抛出的是IOException
带资源的try语句的最简形式为:
try(Resource res = ...){}
try块退出时,会自动调用res.close()。例如:
try(Scanner in = new Scanner(new FileInputStream("/usr/share/dict/words")),"UTF-8"){
while(in.hasNext()){
System.out.println(in.next());
}
}
在存在异常的时候,都会调用in.close()方法,就好像使用了finally块一样
还可以指定多个资源,例如:
try(Scanner in = new Scanner(new FileInputStream("..."),"UTF-8");PrintWriter out = new PrintWriter("out.txt")){
while(in.hasNext())
out.println(in.next().toUpperCase());
}
使用了带资源的try语句块之后,原来的异常会重新抛出,而close方法抛出的异常会被抑制。这些异常将会自动捕获,并且addSuppressed方法增加到原来的异常,可以调用getSuppressed方法,它会得到从close方法抛出并被抑制的异常列表
同样,带资源的try语句自身也可以有catch和finally子句,这些子句会在关闭资源之后执行
6.分析堆栈轨迹元素:
堆栈轨迹是一个方法调用过程的列表,它包含了程序执行过程中方法调用的特定位置
可以使用Throwable类的printStackTrace方法访问堆栈轨迹的文本描述信息
Throwable t = new Throwable();
StringWriter out = new StringWriter();
t.printStackTrace(new PrintWriter(out));
String description = out.toString();
也可以使用getStackTrace方法,它会得到StackTraceElement对象的一个数组
StackTraceElement类含有能够获得文件名和当前执行代码行号的方法,同时,还含有能够获得类名和方法名的方法
静态的Thread.getAllStackTrace方法,它可以产生所有线程的堆栈轨迹,例如:
Map<Thread,StackTraceElement[]> map = Thread.getAllStackTrace();
for(Thread t : map.keySet()){
StackTraceElement[] f = map.get(t);
}
7.java.lang.Throwable 1.0:
Throwable(Throwable cause) 1.4
Throwable(String message,Throwable cause) 1.4
用给定的原因构造一个Throwable对象
Throwable initCause(Throwable cause) 1.4
将这个对象设置为原因,如果这个对象已经被设置为原因,则抛出一个异常,返回this引用
Throwable getCause() 1.4
获得设置为这个对象的原因的异常对象,如果没有,返回null
StackTraceElement[] getStackTrace() 1.4
获得构造这个对象时调用堆栈的跟踪
void addSuppressed(Throwable t) 7
为这个异常增加一个抑制异常
Throwable[] getSuppressed() 7
得到这个异常的所有“抑制”异常
8.java.lang.Exception 1.0:
Exception(Throwable cause) 1.4
Exception(String message,Throwable cause)
用给定的原因构造一个异常对象
9.java.lang.RuntimeException 1.0:
RuntimeException(Throwable cause) 1.4
RuntimeException(String message,Throwable cause) 1.4
用给定的原因构造一个RuntimeException对象
10.java.lang.StackTraceElement 1.4:
String getFileName()
返回这个元素运行时对应的源文件名。
int getLineNumber()
返回这个元素运行时对应的源文件行数
String getClassName()
返回这个元素运行时对应的类完全限定名
String getMethodName()
返回这个元素运行时对应的方法名
boolean isNativeMethod()
如果这个元素运行时在一个本地方法中,则返回true
String toString()
如果存在的话,返回一个包含类名、方法名、文件名和行数的格式化字符串