本帖最后由 马年出黑马 于 2014-5-3 15:04 编辑
张*奇同学成功挑逗起了我钻牛角尖的情绪,昨天看到你那个Exception问题已经1点了,本来打算睡觉,结果又想了一个小时,欲罢不能。 首先把张同学原问题帖一下:(是张图片) 现在有一点自己的想法,你们看看有没有道理: 首先结论:前面的FileNotFoundException的确被catch(IOException e)抓获了,没有显示抛出是因为在作出抛出动作前要先执行finally。 解释: 控制台显示异常信息,是JVM调用了异常对象的printStackTrace()方法,打印方法调用栈的异常信息。也就意味着JVM找不到处理此异常的catch块了,他自己处理了,而JVM自己处理异常会做两个事情: 第一、调用异常的对象的printStackTrace()方法,打印方法调用栈的异常信息。 第二、如果出现异常的线程为主线程,则整个程序运行终止;如果非主线程,则终止该线程,其他线程继续运行 至此,我们知道,一旦JVM自己处理异常就意味着线程要终止,所以finally语句一定要在JVM处理异常前执行,否则将没有执行机会,也就没有了他的意义。 至此分析原问题就明了了,前面我们catch了IOException,转而抛出了RuntimeException,而这个RuntimeException我们没有其他的程序处理他了,JVM判断只能对他做第一、第二处理了,但在这之前要先来把finally做了,不巧,finally里也有个没人处理的异常,JVM就针对它执行了第一、第二,线程终止了,前面没处理的那个也没机会了(当然,我们看到如果finally执行的妥妥的,程序执行完finally后就回去处理之前那个异常了) 这样推断下来,我们发现,如果是单线程的话,其实JVM只有一次printStackTrace()在控制台显示异常信息的机会,也就是说不管有几个没人处理的异常(也不加e.printStackTrace();语句),只有一个有在控制台露脸的机会。是不是这样呢?我还没有验证,你们觉得呢?
我的验证代码:
- <p><p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p><p style="line-height: 30px; text-indent: 2em;"></p>import java.io.*;
- public class Test {
- static BufferedReader br=null;
- static BufferedWriter bw=null;
- public static void main(String[] args) throws Exception {
- try{
- BufferedReader br=new BufferedReader(new FileReader("stu.txt"));
- BufferedWriter bw=new BufferedWriter(new FileWriter("M:\\stu.txt"));//故意找了个无效目录,会抛出FileNotFoundException
- String line=null;
- while((line=br.readLine())!=null) {
- System.out.println(line);
- bw.write(line);
- bw.newLine();
- bw.flush();
- }
- }
- catch(IOException e) { //这里能抓到FileNotFoundException</p><p> //e.printStackTrace(); //其实加上这一句,就能从控制台看到异常信息了
- System.out.println("zhixing");//用来验证是否抓到
- throw new FileNotFoundException("读写失败");
- }
- finally {
- try {
- if(br!=null) {
- br.close();
- }
- }
- catch(IOException e) {
- throw new NullPointerException("流关闭异常");
- }
- try {
- // if(bw!=null) //故意让这里抛出个异常
- bw.close();
-
- }
- catch(IOException e) {
- throw new RuntimeException("流关闭异常");
- }
- catch(RuntimeException e) { //把NullPointerException抓过来
- System.out.println("处理了!");//将下面一行注释掉,不抛出,FileNotFoundException("读写失败")就成功打印!
- //throw new NullPointerException("空指向异常");//抛出了,就得JVM做处理,控制台打印了这个后线程就终止了
- }
- }
- }
- }</p></p>
复制代码
|