黑马程序员技术交流社区

标题: 看看try语句中exception为什么没抛出 [打印本页]

作者: 程金    时间: 2012-9-20 21:15
标题: 看看try语句中exception为什么没抛出
本帖最后由 程金 于 2012-9-21 13:12 编辑
  1. package test;

  2. public class BException extends Exception {
  3.         
  4.         public static void main(String[] args) throws Exception {
  5.                 ThrowException te = new ThrowException();
  6.                 try {
  7.                 te.f();//这个方法应该抛出异常BException,但是控制台上没有抛出,没有错误信息,这是怎么回事???
  8.                 } finally {
  9.                 te.dispose();//这个方法按预期抛出了AException,把这句注释掉的话,前面try语句里面的方法又能抛出异常到控制台了了

  10.                 }
  11.         }
  12. }

  13.         class AException extends Exception {
  14.         }

  15.          class ThrowException {
  16.                         void f() throws BException {
  17.                         throw new BException();//抛出异常
  18.                         }
  19.                         void dispose() throws AException {
  20.                         throw new AException();//抛出异常
  21.                         }
  22.          }
  23.          
  24.          //本来try语句中和finally语句应该都会抛出一个异常,
  25.         // 但是try语句并没有抛出异常,而finally抛出了异常
  26.          //try语句先执行,为什么没有抛出异常呢?很奇怪
  27. //try语句里面那个没有被捕获的exception肯定会抛出,如果虚拟机都不会去处理,谁去处理?掩盖这个异常?假如这个异常很重要呢

  28. 输出结果:
  29. Exception in thread "main" test.AException
  30.     at test.ThrowException.dispose(BException.java:23)
  31.     at test.BException.main(BException.java:10)

  32.          
复制代码

作者: 梁志冰    时间: 2012-9-20 21:42
class BException extends Exception {
        public static void main(String[] args) throws Exception {
                ThrowException te = new ThrowException();
                try {
                te.f();//这个方法应该抛出异常BException,但是没有抛出,这是怎么回事
                System.out.println("try没有抛异常");
                }
               catch(Exception e){System.out.println("已经抛出异常");}  //这里添加打印语句,发现其实try已经抛出了异常
                                finally {
                te.dispose();//这个方法按预期抛出了AException,
                }
        }
}
        class AException extends Exception {
        }
         class ThrowException {
                        void f() throws BException {
                        throw new BException();//抛出异常
                        }
                        void dispose() throws AException {
                        throw new AException();//抛出异常
                        }
         }
         //本来try语句中和finally语句都会抛出一个异常,
        // 但是try语句并没有抛出异常,而finally抛出了异常
         //try语句先执行,为什么没有抛出异常呢?很奇怪

答:如上面的程序,我们添加两个打印语句,并对try进行捕获,运行结果如下:
已经抛出异常
Exception in thread "main" AException
        at ThrowException.dispose(FinalDemo.java:21)
        at BException.main(FinalDemo.java:10)

其实try语句中的异常已经抛出了,只是没有对其进行捕获,而且在主函数上throws
Exception 声明了Exception异常
直接抛给了虚拟机,虚拟机没有对其进行任何的处理,也没有打印输出,所以你感觉不出来。

对其增加
catch(Exception e){System.out.println("已经抛出异常");}  语句进行捕获,并对其进行打印处理,我们就能很
清楚的知道整个异常的处理。

finally是一定会执行到的,只有在执行finally前,执行System.exit(0);语句,让虚拟机执行结束,才不会执行到finally语句

作者: 程金    时间: 2012-9-20 22:10
本帖最后由 程金 于 2012-9-20 22:21 编辑
梁志冰 发表于 2012-9-20 21:42
class BException extends Exception {
        public static void main(String[] args) throws Exception ...

回答有问题 你把finally去掉你看看,异常就抛了,怎么会jvm不处理.谁说要catch捕获才会打印错误信息,
try语句里面那个没有被捕获的exception肯定会抛出,如果虚拟机都不会去处理,谁去处理?掩盖这个异常?假如这个异常很重要呢

作者: 梁志冰    时间: 2012-9-20 22:47
程金 发表于 2012-9-20 22:10
回答有问题 你把finally去掉你看看,异常就抛了,怎么会jvm不处理.谁说要catch捕获才会打印错误信息,
try语 ...

我不知道您说的把finally去掉是怎么个去掉法?您是说在我没有加catch代码前去掉的吗?如果是这样,那么这就变成了编译异常。也就是说虚拟机在对您的程序进行编译的时候,发现的语法异常,这个时候虚拟机就会对其特征进行相应的异常处理。这是因为try{}后面必须要跟catch(){}或finally{}等形式。
因为您在主函数中声明的是Exception异常,不是说Exception不处理,而是它的处理方式比较特殊,即不进行输出,也不直接结束程序。
catch(){}是捕获异常,并对其进行相应的处理,我在你程序中使用的处理方式是打印输出。当然,这个处理方式是可以由您自己定的。您可以选择让程序结束,也可以提示修改等等....
作者: 程金    时间: 2012-9-20 23:01
梁志冰 发表于 2012-9-20 22:47
我不知道您说的把finally去掉是怎么个去掉法?您是说在我没有加catch代码前去掉的吗?如果是这样,那么这 ...

说错,我是说把finally里面的语句去掉
作者: 明光照    时间: 2012-9-21 00:01
这个异常应该是捕获了的。只是你没有处理,就直接执行finally了,所以在执行finally的时候会抛出异常。
        try {

                        te.f();
System.out.println("执行了吗");//加上这句后运行发现并没有打印,这说明上面已经出了问题。
                       

                }
作者: 程金    时间: 2012-9-21 09:38
明光照 发表于 2012-9-21 00:01
这个异常应该是捕获了的。只是你没有处理,就直接执行finally了,所以在执行finally的时候会抛出异常。
        tr ...

服了你,想明白了再说, te.f()方法都抛出异常了,并且没手动捕获,下面一句肯定不打印了
作者: 梁志冰    时间: 2012-9-21 22:45
程金 发表于 2012-9-20 23:01
说错,我是说把finally里面的语句去掉

class BException extends Exception {
        BException(String x){
     System.out.println(x);}   //增加构造函数,打印异常
public static void main(String[] args) throws Exception {
    ThrowException te = new ThrowException();
    try {
          te.f();//这个方法应该抛出异常BException,但是没有抛出,这是怎么回事
        }
        finally {
         te.dispose();//这个方法按预期抛出了AException,把这句注释掉的话,前面try语句里面又能抛出异常了
        }
   }
}
class AException extends Exception {
  AException(String x){
System.out.println(x);} //增加构造函数,打印异常
}
class ThrowException {
     void f() throws BException {
      //  throw new BException();//抛出异常
                 throw new BException("B");//抛出异常
       }
     void dispose() throws AException {
       //  throw new AException();//抛出异常
         throw new AException("A");//抛出异常
       }
}

运行结果1:(保留finally中的异常)
B
A
Exception in thread "main" AException
        at ThrowException.dispose(ExceptionDemo.java:25)
        at BException.main(ExceptionDemo.java:10)

分析:
1、通过运行结果,我们可以看到,其实te.f()已经抛出了异常,打印了B
2、虚拟机收到了te.f()抛出的异常BException,但它没有执行处理,因为try{}后面跟了一个finally{}
3、我们知道finally{}是在虚拟机停止前必须要执行的。所以虚拟机收到BException异常,并没有执行处理,而是执行了finally{}中的语句
4、执行finally中的语句中发现, te.dispose()抛出AException,打印了A,这时虚拟机执行处理AException,并对其进行相应的处理,打印异常信息,停止虚拟机
5、虚拟机一旦停止,前面收到的te.f()抛出的异常BException,就没进行处理啦,因为虚拟机已经停止了

运行结果2:(注释finally中的异常)
B
Exception in thread "main" BException
        at ThrowException.f(ExceptionDemo.java:21)
        at BException.main(ExceptionDemo.java:7)

分析:
1、通过运行结果,我们可以看到,其实te.f()已经抛出了异常,打印了B
2、虚拟机收到了te.f()抛出的异常BException,但它没有执行处理,因为try{}后面跟了一个finally{}
3、我们知道finally{}是在虚拟机停止前必须要执行的。虚拟机这时开始执行执行finally{}
4、执行完finally{} 后,虚拟机继续运行,处理前面收到的异常BException,
打印异常信息,停止虚拟机,程序结束

综上所述,就可以清晰的了解到上述运行结果的原因:运行结果1中其实是因为finally抛出的异常处理完后,虚拟机结束了,就没有再对之前收到的异常BException
进行处理。
而运行结果2是因为finally中没有让虚拟机结束,所以会进行回来处理之前收到的异常BException

希望以上解答对你有所帮助!








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2