如果出现错误,程序会显示意外行为

时间:2013-10-28 14:22:46

标签: java try-catch

我只是尝试使用try-catch和这段代码:

public class MainThread
{
    public static void main(String [] args) 
    {
        try 
        {
            badMethod();  
            System.out.print("A"); 
        }  
        catch (Exception ex) 
        {
            System.out.print("B");  
        } 
        finally 
        {
            System.out.print("C"); 
        } 
        System.out.print("D"); 
    }  
    public static void badMethod() 
    {
        throw new Error(); /* Line 22 */
    } 
}

我理解上面的Error块不会捕获catch,但会执行finally块,然后JVM将终止。

但是当我尝试多次运行程序时,我会得到不同的输出:

在堆栈跟踪之前打印

C

CException in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)
堆栈跟踪后打印

C

Exception in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)
C

任何人都可以解释这种行为吗?

2 个答案:

答案 0 :(得分:11)

System.out流和System.err流是分开的流,两者都具有相同的输出。因此,他们之间存在竞争,而且“胜利”无法提前确定。

正如Luiggi Mendoza所说;

  

为了获得理想的结果,OP必须改变   系统.out.print到System.error.print或捕获错误并打印它   使用e.printStacktrace(System.out)。或者甚至更好,使用记录器   为您处理所有这些工作

另外值得注意的是,你的catch语句没有抓住这个new Error(),因为Error!= Exception

答案 1 :(得分:1)

更改

    catch (Exception ex) 

    catch (Throwable ex) 

获得更多(Throwable是基类)。它还捕获badMethod中的堆栈跟踪,它可能e.printStacktrace(),它调用e.printStacktrace(System.err)Exception用于检查Exception,而不是RuntimeExceptions。

对于控制台,编写器(PrintStreams),System.out和System.err都是在不同的线程中同时写入的:所以真的很混乱。