【问题标题】:Exception output not coming in sequence异常输出不按顺序出现
【发布时间】:2013-01-16 06:02:14
【问题描述】:

我的代码如下:

public class BoxingUnboxingExample {
    public static void main(String[] args) {
        Integer i1 = null;
        Integer i3 = 10;
        BoxingUnboxingExample b = new BoxingUnboxingExample();
        b.go(i3);
        b.go(i1);
    }
    private void go(int a){
        System.out.println("a");
    }
}

现在我的问题是:

有时我会收到以下错误消息,

Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
a

然而,我认为它应该始终如下,

a
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)

我说的对吗?

【问题讨论】:

    标签: java core


    【解决方案1】:

    一个原因可能是异常堆栈跟踪使用standard error (System.err) 输出错误数据,而System.out.println 使用standard output (System.out)

    这意味着两者都使用不同的机制来输出数据,这些可能无法正确同步。

    您也可以参考这个earlier question

    【讨论】:

      【解决方案2】:

      如果您在 Eclipse 中,这是一个已知问题,请参阅 https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205

      【讨论】:

        【解决方案3】:

        输出和错误是两个不同的流System.errSystem.out

        阅读:

        标准输出和标准错误是可以接受且正常的 被定向到相同的目的地,例如文本终端。 消息的出现顺序与程序编写它们的顺序相同,除非 涉及缓冲。 (例如,常见的情况是当 标准错误流是无缓冲的,但标准输出流是 行缓冲;在这种情况下,稍后写入标准错误的文本可能 较早出现在终端上,如果标准输出流的缓冲区 还没满。)

        来自wikipeda

        所以你的输出流(System.out.println)实际上是缓冲的。它在内部调用BufferedWriter.write() 方法。看看这个: How System.out.println() really works

        【讨论】:

        • 这并不能解释为什么输出是这样的。
        • 当然,该方法需要一个 int 并且它的 beeing 使用 null 调用,Integer 是一个引用,因此它可以为 null,但 in 是一个优先类型,它不能为 null。
        • @MeNoMore:当然,但这不是问题——他的问题是关于“a”和异常信息的显示顺序,与语句的顺序不对应执行。第一次调用有一个 int,所以它应该首先显示(“a”),只有在第二次调用之后才会显示异常。
        【解决方案4】:

        这里至少有 2 个效果在起作用,都与 System.outSystem.err 如何(自然)是 2 个不同的流有关。

        缓冲

        System.errSystem.out 都是 PrintStream,默认情况下会缓冲,但是 System.err 通常设置为在每次写入后(字节数组或每当写入换行符时)自动刷新。

        因此,如果System.errSystem.out 被刷新之前被刷新,它将首先出现在屏幕上。

        读取这些流

        在编辑器中,System.outSystem.err 在单个控制台中显示的情况并不少见。发生这种情况的方式将影响它们的显示顺序。 Eclipse 有 2 个进程,每个流一个,用于从流中读取并显示它们。它们读取(以及显示)的顺序是不确定的。如果两个流都准同时写入,则从System.err 读取的进程将有 50% 的机会首先接收输入。因此,它们可能看起来是随机交错的。

        【讨论】:

          【解决方案5】:
          public class Main {
          
                  public static void main(String[] args) {
                      System.setErr(System.out); // this line seems to solve the problem
                      System.out.println("test");
          
                      throw new RuntimeException("Test");
                  }
          
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多