黑马程序员技术交流社区

标题: 关于异常输出顺序的疑问 [打印本页]

作者: Walking Walking    时间: 2013-3-10 17:13
标题: 关于异常输出顺序的疑问
本帖最后由 徐盼盼 于 2013-3-10 17:18 编辑

做异常的练习的时候做了以下的测试代码:
class ExceptionTest {
        
        public static void testException() throws Exception{ //throws 声明方法会抛出异常
               
                String s="";
                try{
                        System.out.println(s.toString()); //这里发生异常
                        throw new Exception(); //在try中抛出异常 ,说明在try中可以抛出异常
                        
                }catch(Exception e){ //catch是捕获抛出的异常
                        
                        System.out.println("抛出捕获到的异常");
                        throw e;
                        
                }finally{
                        System.out.println("in finally"); //finally不管异常是否发生总会被执行
                }
        }

        /**
         * @param args
         */
        public static void main(String[] args) {
               
                try {
                        ExceptionTest.testException();
                }catch(Exception e){
                        e.printStackTrace();
                }
        }

}

期望的输出顺序应该是:
抛出捕获到的异常
in finally
java.lang.Exception
        at ExceptionTest.testException(ExceptionTest.java:15)
        at ExceptionTest.main(ExceptionTest.java:33)
但是实际上顺序有时候的结果是这样的:
java.lang.Exception
抛出捕获到的异常
in finally
        at ExceptionTest.testException(ExceptionTest.java:15)
        at ExceptionTest.main(ExceptionTest.java:33)

或者
java.lang.Exception
at ExceptionTest.testException(ExceptionTest.java:15)
at ExceptionTest.main(ExceptionTest.java:33)
抛出捕获到的异常
in finally
这个就不理解了,难道是e.printStackTrace()是异步的吗?那如何将异步改为同步呢?

作者: 李辉    时间: 2013-3-10 18:54
      首先你这个程序里面不存在同步异步的问题,同步异步是多线程的时候考虑的,你这个程序是单线程执行的。
public static void main(String[] args) {
               
                try {
                        ExceptionTest.testException();
                }catch(Exception e){
                        e.printStackTrace(System.out);
                }
        }
你的程序的主函数改成我这样就没问题了!就是多了一个System.out参数,这是在指定流对象。
    根据你对程序输出的猜想可以看出来你能分析出程序执行的过程,之所以出现那种输出是因为你没有指定e.printStackTrace();用哪个流对象来输出,默认情况会重新创建一个流对象,而不是使用System.out。
    其实不管你是否指定流对象参数,程序执行路径还是你设想的那样的,只是两个输出流在竞争时,打印出的东西就没有顺序了。
作者: _王涛    时间: 2013-3-17 22:03
同意楼上的..




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