Java异常处理

一、异常分类

在Java程序设计语言中,异常对象都是派生于Throwable类的一个实例。但在下一层立即分解为两个分
支:Error 和 Exception。
Java中的异常层次结构
Error 类层次结构描述了 Java 运行时系统的内部错误和资源耗尽错误。 应用程序不应该抛出这种类型的对象。 如果出现了这样的内部错误, 除了通告给用户,并尽力使程序安全地终止之外, 再也无能为力了。这种情况很少出现。
在设计 Java 程序时, 需要关注 Exception 层次结构。 这个层次结构又分解为两个分支:一个分支派生于 RuntimeException ; 另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于 RuntimeException ; 而程序本身没有问题, 但由于像 I/O 错误这类问题导致的异常属于其他异常。
派生于 RuntimeException 的异常包含下面几种情况:

  • 错误的类型转换。
  • 数组访问越界。
  • 访问 null 指针。

不是派生于 RuntimeException 的异常包括:

  • 试图在文件尾部后面读取数据。
  • 试图打开一个不存在的文件。
  • 试图根据给定的字符串查找 Class 对象, 而这个字符串表示的类并不存在。

“ 如果出现 RuntimeException 异常, 那么就一定是你的问题” 是一条相当有道理的规则。
Java 语 言 规 范 将 派 生 于 Error 类 或 RuntimeException 类的所有异常称为非受查( unchecked ) 异常,所有其他的异常称为受查( checked) 异常。

二、异常的使用

	public void exception() throws Exception {
		throw new Exception();
	}

	public void run() {
		throw new RuntimeException();
	}

三、创建异常类

public class FileFormatException extends IOException{
	public FileFormatExceptionO {}
	public FileFormatException(String gripe){
	super(gripe);
	}
}

四、捕获异常

如果某个异常发生的时候没有在任何地方进行捕获,那程序就会终止执行,并在控制台
上打印出异常信息, 其中包括异常的类型和堆栈的内容。

4.1 捕获异常

/** 捕获异常的语法 */
try{
	more code
}catch (ExceptionType e){
	handlerfor this type
}

4.2 捕获多个异常

try{
	code that might throwexceptions
}
catch (FileNotFoundException e){
	emergencyactionfor missingfiles
}
catch (UnknownHostException e){
	emergency actionfor unknown hosts
}
catch (IOException e){
	emergencyactionfor all other I/O problems
}

在 Java SE 7中,同一个 catch 子句中可以捕获多个异常类型。例如,假设对应缺少文件
和未知主机异常的动作是一样的,就可以合并 catch 子句:

try{
	code that might throw exceptions
}catch (FileNotFoundException | UnknownHostException e){
//捕获多个异常时,异常变量隐含为final变量。例如,不能在以上子句体中为e赋不同的值
	emergency action for missing files and unknown hosts
}catch (IOException e){
	emergency action for all other I/O problems
}

4.3 再次抛出异常与异常链

在catch子句中可以抛出一个异常,这样做的目的是改变异常的类型。也可能是需要做一些处理之后再次抛出异常。

try{
	access the database
}catch (SQLException e){
	throw new ServletException("database error: " + e.getMessageO);
}

/* 或使用包装技术 */
try{
	access the database
}catch (SQLException e){
	Throwable se = new ServletException ("database error");
	se.initCause(e)
}

如果在一个方法中发生了一个受查异常, 而不允许抛出它, 那么包装技术就十分
有用。我们可以捕获这个受查异常,并将它包装成一个运行时异常。

4.4 finally子句

不管是否有异常被捕获,finally 子句中的代码都被执行。

try{
	more code
}catch (ExceptionType e){
	handlerfor this type
}finally{

}

4.5 带资源的try语句

try (Resource res = . . .){
	work with res
}

假设资源属于一个实现了 AutoCloseable 接口的类,AutoCloseable 接口有一个方法:
void close() throws Exception
Java SE 7 为这种代码模式提供了一个很有用的快捷方式(带资源的try语句)。try块退出时,会自动调用res.close()。
另外,还有一个 Closeable 接口。这是 AutoCloseable 的子接口, 也包含一个 close方法。不过, 这个方法声明为抛出一个 IOException。

4.6 分析堆栈轨迹元素

堆栈轨迹( stack trace ) 是一个方法调用过程的列表, 它包含了程序执行过程中方法调用的特定位置。当Java 程序正常终止, 而没有捕获异常时, 这个列表就会显示出来。
可以调用 Throwable 类的 printStackTrace 方法访问堆栈轨迹的文本描述信息。

Throwable t = new Throwable()StringWriter out = new StringWri ter() ;
t.printStackTrace(new PrintWriter(out));
String description = out.toString();

一种更灵活的方法是使用 getStackTrace 方法, 它会得到 StackTraceElement 对象的一个数组, 可以在你的程序中分析这个对象数组。例如:

Throwable t = new ThrowableO ;
StackTraceElement[] frames = t.getStackTrace();
for (StackTraceElement frame : frames)
analyze frame

StackTraceElement 类含有能够获得文件名和当前执行的代码行号的方法, 同时, 还含有能够获得类名和方法名的方法。toString 方法将产生一个格式化的字符串, 其中包含所获得的信息。
静态的 Thread.getAllStackTrace 方法, 它可以产生所有线程的堆栈轨迹 . 下面给出使用这个方法的具体方式:

Map<Thread, StackTraceElement[]> map = Thread.getAl1StackTraces();
for (Thread t : map. keySet ()){
StackTraceElement[] frames = map.get(t);
	analyze frames
}

五、总结

5.1 throw 和 throws 的区别

  • throw:是真实抛出一个异常。
  • throws:是声明可能会抛出一个异常。

5.2 final、finally、finalize 有什么区别?

  • final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
  • finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果 finally 部分存在,则一定会执行 finally 里面的代码。
  • finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。

5.3 try-catch-finally 中哪个部分可以省略?

try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。

5.4 try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗

finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。

5.5 常见的异常类有哪些

  • NullPointerException 空指针异常
  • ClassNotFoundException 指定类不存在
  • NumberFormatException 字符串转换为数字异常
  • IndexOutOfBoundsException 数组下标越界异常
  • ClassCastException 数据类型转换异常
  • FileNotFoundException 文件未找到异常
  • NoSuchMethodException 方法不存在异常
  • IOException IO 异常
  • SocketException Socket 异常
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值