【问题标题】:In case of Error, program shows unexpected behavior [duplicate]如果出现错误,程序会显示意外行为 [重复]
【发布时间】:2013-10-28 14:22:45
【问题描述】:

我只是在尝试使用 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

谁能解释这种行为?

【问题讨论】:

    标签: java try-catch


    【解决方案1】:

    System.out 流和System.err 流是两个具有相同输出的独立流。因此,他们之间存在着一场竞赛,无法提前确定“胜负”。

    正如路易吉·门多萨所说;

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

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

    【讨论】:

    • +1 表示答案很棒
    • 为了得到想要的结果,OP 只需将System.out.print 更改为System.error.print 或捕获Error 并使用e.printStacktrace(System.out) 打印它。或者更好的是,使用为您处理所有这些工作的记录器。
    【解决方案2】:

    改变

        catch (Exception ex) 
    

    进入

        catch (Throwable ex) 
    

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

    对于控制台,两个编写器 (PrintStreams)、System.out 和 System.err 是在不同的线程中同时写入的:所以真的混在一起了。

    【讨论】:

    • 我知道 Throwable 可以使用,但@Richard 回答了我正在寻找的内容。尽管您的回答也提供了很好的信息。 +1:)
    • 谢谢,他是第一个。我只是想指出 Throwable;有点冗长,因为其他人将来可能会寻求问题+答案。
    • 不过,关于不同线程的部分是错误的;单独的缓冲区,相同的线程。
    • @ErnestFriedman-Hill 所以重复运行应该在相同条件下导致相同的乱码控制台?谢谢。
    • 不确定的行为来自操作系统;如果 Java 程序不刷新缓冲区,则取决于操作系统何时从每个缓冲区中提取数据并显示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多