Java之美[从菜鸟到高手演变]之Exception
Exception这个东西,程序中必须会有的,尽管我们很不乐意看到它,可是从另一个角度考虑,有异常则说明程序有问题,有助于我们及时改正。有的时候程序出错的原因有很多,比如不合法的输入、类型、空指针甚至内存不足,如果光从软件来看,我们只知道它出问题了,并不清楚问题出在哪儿,给软件排错是个很头疼的事情,因为可能出问题的地方太多了,语法上的问题还好点儿,毕竟能从视觉上看出来,有些逻辑上的问题才是致命的,我们必须从全局出发也许才能找到问题的根源!基于这些,我们需要借助于异常机制。记得刚学习写程序的时候,老师总说在有可能出错的地方,别忘了加入异常处理块,当时我就想,既然是自己写的东西,难道还不知道会不会出错?当时在一段时间内这个问题困扰着我,殊不知程序哪有那么简单,后来自己写得多了才清楚了,异常很重要!本章系Java之美[从菜鸟到高手演变]系列之Exception,通过本章的学习,我们可以基本较为深入的理解Java中异常处理机制。
在阅读过程中有任何问题,请及时联系:egg。
一、简介
Java为我们提供了非常完美的异常处理机制,使得我们可以更加专心的去写程序,有的时候遇到需要添加异常处理块的地方,像eclipse会自动提示你,感觉很幸福!我们看看异常处理的一些类的结构组成:
从根部开始分为两大类:Error和Exception。Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。Exception是程序本身可以处理的异常,这种异常分两大类:非运行时异常(发生在编译阶段,又称checkException)和运行时异常(发生在程序运行过程中,又叫uncheckException)。非运行时异常一般就是指一些没有遵守Java语言规范的代码,容易看的出来,并且容易解决的异常,运行时异常是那些在程序运行过程中产生的异常,具有不确定性,如空指针异常等,造成空指针的原因很多,所以运行时异常具有不确定性,往往难以排查,还有就是程序中存在的逻辑错误,光从一段代码中看不出问题,需要纵观全局才能发现的错误,也会造成运行时异常,这就要求我们在写程序时多多注意,尽量处理去处理异常,当异常发生时,希望程序能朝理想的方面运行!
二、异常的类型
一方面我们可以将异常分为受控异常和不受控异常,其实一般来讲,受控异常就是非运行时异常,不受控异常就是运行时异常和Error。另一方面,我们直接将异常分为非运行时异常和运行时异常。
三、异常处理的过程
使用try/catch/finally语句块安装异常处理程序,每个try块中包含可能出现异常的语句,每个catch块中包含处理异常的程序,
public class Test {
public static void main(String[] args) {
String filename = "d:\\test.txt";
try {
FileReader reader = new FileReader(filename);
Scanner in = new Scanner(reader);
String input = in.next();
int value = Integer.parseInt(input);
System.out.println(value);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
System.out.println("this is finally block!");
}
}
}
如果d盘根目录下没有test.txt的话,该程序抛出异常:
this is finally block!
java.io.FileNotFoundException: d:\test.txt (系统找不到指定的文件。)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at java.io.FileReader.<init>(FileReader.java:41)
at Test.main(Test.java:10)
但是finally块中的语句却输出了,这个暂且不谈,先记着,在d盘下新建文件test.txt,并输入内容2232,再来观察下:
输出:
2322
this is finally block!
finally块中的语句依然输出,说明:不论程序有无异常,finally块中的语句都会执行。因此finally块中一般放一些关闭资源的语句。接下来我们继续做实验,我们将test.txt中的2322改成abc,看看结果:
this is finally block!
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.lang.Integer.parseInt(Integer.java:497)
at Test.main(Test.java:13)
该异常中的两处重点我已经标出来了,一处是红色的Exception in thread “main”,表明异常抛出的地方,另一处是java.lang.NumberFormatException: For input string: "abc",表明异常的类型,此处我们看看上面之前的那个结果,为什么没有抛出异常出现的地方,仔细观察源程序,我们发现,程序中我们并没有显式声明NumberFormatException,而FileNotFoundException是我们声明过的,此处我总结一下就是说:1、如果我在程序中声明了某个异常,则抛出异常的时候,不会显式出处,直接抛出。2、如果我没有在程序中声明,那么程序会同时抛出异常的出处。这是为什么?还有,当我没有显式声明的时候,系统会怎么办?这肯定是有一定的规律的,下面我们继续做实验:
[java]
public class Test {
public static void main(String[] args) {
String filename = "d:\\test.txt";
// 进行捕捉异常
try {
FileReader reader = new FileReader(filename);
Scanner in = new Scanner(reader);
String input = in.next();
int value = Integer.parseInt(input);
System.out.println(value);
} catch (FileNotFoundException e) { // 捕捉FileNotFoundException
e.printStackTrace();
} catch (NumberFormatException e) { // NumberFormatException
e.printStackTrace(); // 打印异常信息 就是形如:at java.lang.NumberFor...的信息
System.out.println("I'm here!");
} finally {
System.out.println("this is finally block!");
}
}
}
我加了一个catch块,转么捕获NumberFormatException,则程序输出:
java.lang.NumberFormatException: For input string: "abc"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.lang.Integer.parseInt(Integer.java:497)
at Test.main(Test.java:14)
I'm here!
this is finally block!
没有输出异常抛出的地方。继续改代码:
[java]
public class Test2 {
public void open(){
补充:软件开发 , Java ,