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

Java 如果出现错误,程序将显示意外行为,java,try-catch,Java,Try Catch,我只是用try-catch和以下代码尝试了一些东西: public class MainThread { public static void main(String [] args) { try { badMethod(); System.out.print("A"); } catch (Exception ex) {

我只是用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 */
    } 
}
我知道上面的
catch
块不会捕捉到
Error
,但是
最终将执行
块,然后JVM将终止

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

C
在堆栈跟踪之前打印:

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

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

有人能解释这种行为吗?

系统.out
流和
系统.err
流是具有相同输出的独立流。因此,他们之间存在一场竞赛,而“胜利”无法事先确定

正如Luiggi Mendoza所说

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

另外值得注意的是,catch语句没有捕获此
newerror()
,因为
Error
=<代码>异常

更改

    catch (Exception ex) 
进入

其中捕获更多(Throwable是基类)。它还捕获badMethod中的堆栈跟踪,该方法可能会调用
e.printStacktrace()
,调用
e.printStacktrace(System.err)
<代码>异常用于检查异常,而不是运行时异常


控制台上的两个写入程序(PrintStreams)、System.out和System.err都是同时写入的,在不同的线程中:所以真的混淆了。

+1为了获得所需的结果,答案中的惊人之处,OP只需将
System.out.print
更改为
System.error.print
或捕获
错误
,并使用
e.printStacktrace(System.out)
进行打印。或者更好的办法是,使用一个能为您处理所有这些工作的记录器。我知道可以使用Throwable,但是@Richard回答了我的问题。虽然你的答案也提供了很好的信息+1:)谢谢,他是第一个。我只是想指出关于抛弃的问题;在一些冗长的问题+答案可能会寻求在未来的其他人。部分关于不同的线程是错误的,虽然;不同的缓冲区,相同的线程。@ErnestFriedman Hill那么重复运行应该会在相同条件下导致相同的混乱控制台吗?谢谢。不确定行为来自操作系统;如果Java程序不刷新缓冲区,则由操作系统决定何时从每个缓冲区中提取并显示数据。