一、 基本概念
当出现程序无法控制的外部环境问题(例如,网络不可用,用户提供的文件不存在,文件内容损坏...)时,Java就会用异常对象来描述。
JAVA中用2中方法处理异常:
(1) 在发生异常的地方直接处理;
(2) 将异常抛给调用者,让调用者处理。
二、异常分类
(1) 检查性异常:java.lang.Exception;
(2) 运行期异常:java.lang.RuntimeException;
(3) 错误:java.lang.Error。
顶层是java.lang.Throwable类,无论是检查性异常、运行期异常,还是错误异常,都是这个类的子类。java.lang.Exception和java.lang.Error继承自java.lang.Throwable,而java.lang.RuntimeException继承自java.lang.Exception。
检查性异常:程序正确,但因为外在的环境条件不满足引发。比如,试图打开一个不存在的文件,或者打开一个并不存在的远程Socket端口。这不是程序本身的逻辑错误。java编译器强制要求处理这类异常,如果不捕获这类异常,程序将不能被编译。
package Test25;
import java.io.FileReader;
import java.net.Socket;
public class Test25_3 {
public static void main(String[] args) {
// 1.打开一个文件
FileReader fr = new FileReader("d:\\hello.txt"); //编译器强制要求捕获并处理该异常
// 2.连接一个IP
Socket s = new Socket("192.168.1.23",78); //编译器强制要求捕获并处理该异常
}
}
运行期异常:这意味着程序存在bug,如数组越界,除数为0等。这类异常需要更改程序来避免。
错误:一般很少见,也很难通过程序解决。它可能源于程序的bug,但一般更可能源于环境问题,如内存耗尽。错误在程序中无需处理,而由运行环境处理。
三、 异常处理
3.1 try...catch
try包含可能会出现异常的代码块;
catch包含当try块中出现处理时会执行的代码;
import java.io.FileReader;
public class Test25_3 {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("d:\\hello.txt");
//在出现异常的地方,就终止执行代码,然后进入到catch里面
System.out.println("111");
}
catch(Exception e){
System.out.println("222");
System.out.println(e.getMessage());
}
System.out.println("333");
}
}
3.2 try...catch...finally
catch 和 finally 语句都是可选的,但在使用 try 语句时必须至少使用一个。
finally在try...catch之后,无论有无异常一般都会执行,即使前面的try或catch块中有return语句,finally依然会执行。通常情况下,finally用于关闭未关闭的资源。
package Test25;
import java.io.FileReader;
public class Test25_4 {
public static void main(String[] args) {
FileReader fr = null;
try {
fr = new FileReader("d:\\hello.txt");
//在出现异常的地方,就终止执行代码,然后进入到catch里面
System.out.println("111");
}
catch(Exception e){
System.out.println("进入catch");
System.out.println(e.getMessage());
}
finally {
System.out.println("进入finally");
// 把需要关闭的资源关闭
if (fr != null) {
try {
System.out.println("关闭文件");
fr.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
System.out.println("Main End!");
}
}
如上代码,如果d盘下没有hello.txt文件,则运行结果如下:
如果d盘下有此代码,则运行结果如下:
以下情况,finally块将不会被执行:
(1) finally块中发生了异常;
(2) 程序所在线程死亡;
(3) 在前面的代码中使用了System.exit();
(4) 关闭CPU。
3.3 抛出异常throws
将异常抛出给调用者,让调用者处理异常。但一般不建议通过抛出异常来处理。
import java.io.FileReader;
public class Test25_5 {
public static void main(String[] args) {
Father f = new Father();
f.test();
}
}
class Father{
public void test()
{
System.out.println("Father test()");
Son s = new Son();
try {
s.test1();
}catch(Exception e) {
System.out.println("Father捕获处理异常!");
}
}
}
class Son{
public void test1() throws Exception
{
FileReader fr = new FileReader("d:\\hello.txt");
}
}
运行结果: