1.什么是异常?
异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的错误条件。当条件生成时,错误将引发异常。Java异常类层次结构如下图所示:
Error:是程序无法处理的错误,大多数错误与代码编写者执行的操作无关,而是与JVM有关,如VirtualMachineError(虚拟机错误)。OutOfMemoryError(内存溢出)包括三种情况:
1)PermGen Space。原因是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够。
2)Java heap space。原因是java虚拟机创建的对象太多,在进行垃圾回收时,虚拟机分配的到堆内存空间已经用满了。
3)unable to create new nativethread。错误在Java线程个数很多的情况下容易发生。
StackOverflowError(堆栈溢出错误)。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。
这些错误发生时,Java虚拟机(JVM)一般会选择线程终止。
Exception:是程序本身可以处理的异常,分为以下两种:
RuntimeException(运行时异常)。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用(NullPointerException)、除数为零(ArithmeticException)或数组越界(ArrayIndexOutOfBoundException)。这些异常是unchecked exceptions,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常或编译异常。除RuntimeException以外的其余的异常。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义checked exceptions。
2.怎么处理异常?
处理异常的方式大致有两种:
1)在发生异常的地方直接处理;
2)将异常抛还给调用者,调用者捕获异常之后处理异常。
捕获异常的方式如下:
try {
methodName();// 可能会发生异常的程序代码
} catch (Exception e) {
e.printStackTrace(); // 捕获并处理try抛出的异常类型
}finally { // 无论是否发生异常,都将执行的语句块
}
当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:(1)在finally语句块中发生了异常。(2)在前面的代码中用了System.exit()退出程序。(3)程序所在的线程死亡。(4)关闭CPU。
抛出异常的方式如下:
public String methodName() throws Exception1,Exception2,..,ExceptionN{
//方法体
}