Java中的错误消息是否像类似Unix的操作系统中那样自动发送到标准错误流?

时间:2019-07-14 19:42:49

标签: java unix stream operating-system outputstream

在类似Unix的操作系统中,标准错误是来自命令行程序的错误消息的目标,而标准错误的默认目标是显示屏。而且我假设就像在类似Unix的操作系统中一样,Java中的每个命令都被分配了三个数据流(即通道):标准输入,标准输出和标准错误

  1. 在Java中是否同样如此?也就是说,在Java中,是命令发出的错误消息立即发送到标准错误流,或者命令发出的错误消息没有目的地(即,命令发出的错误消息不会到达任何地方,除非我们将其捕获到变量中,然后使用System.err.println(e);将其发送到标准错误流?

以下面的代码为例:

ArrayList<String> middleLine = new ArrayList<String>();

int beginIndex = 0;
int endIndex = list.size() - 1;

int middleIndex = (beginIndex + endIndex) / 2;

try {
middleLine.add(lines[middleIndex]);
} catch(Exception e) {
System.err.println(e);
}
  1. 命令middleLine.add(lines[middleIndex]);引发异常。由于Java非常惯用,因此Java关键字throws暗示异常不会自动发送到标准错误流,还是throws指示异常在标准错误输出数据流中的运行?
  2. 在命令middleLine.add(lines[middleIndex]);进入标准错误流之前是否捕获到该异常?
  3. 或者当命令middleLine.add(lines[middleIndex]);已经在标准错误流中时,是否捕获到该命令引发的异常?

静态变量err的Javadoc说:

  

“标准”错误输出流。该流已经打开,可以接受输出数据了

  1. 从Javadoc中摘录的err是否意味着命令System.err.println(e)将使用catch命令捕获的异常e发送到标准错误流?然后,由于默认情况下标准错误流的目标是显示屏,因此方法println将错误输出数据发送到标准错误流,并在此将其自动发送到显示屏?

  2. 当我们将错误消息作为参数的参数println的参数时,是否必须捕获错误消息(即异常)才能将错误消息发送到标准错误输出流标准错误PrintStream对象?这意味着当我们使用System.err.println(e)打印发送到标准错误输出流的错误消息时,由于标准错误流的目标是显示屏,因此该消息显示在计算机屏幕上

  3. 如果catch命令在标准错误输出流中捕获了错误,那么错误消息中是否不再包含错误消息?
  4. 如果catch命令在错误消息进入标准错误流之前捕获了错误消息,该错误消息是否仍发送到标准错误流?
  5. System.err.println(e)是指打印与自动发送到标准错误流的异常匹配的异常e,还是打印通过方法的参数发送到标准错误流的异常e println

1 个答案:

答案 0 :(得分:1)

仅当未捕获到异常,或者您在其上调用printStackTrace()时,该异常才会打印到stderr。这是一个应演示一些内容的小演示:

public class foo {

    public static void main(String[] args) {
        System.out.println("This prints to stdout");
        System.err.println("This prints to stderr");
        int x;
        try {
            x = 1 / 0;
        } catch (ArithmeticException e) {
            System.err.println("Printing stack trace to stderr");
            e.printStackTrace();
            System.err.println("Printing message to stderr");
            System.err.println(e.getMessage());
        }
        try {
            x = 1 / 0;
        } catch (ArithmeticException e) {
            // nothing sent to stderr
        }
        System.out.println("Un-caught exception will kill program and print stack trace to stderr");
        x = 1 / 0;
    }
}

...

Erics-MacBook-Pro:tmp redekopp$ javac foo.java
Erics-MacBook-Pro:tmp redekopp$ java foo > foo-stdout.txt 2> foo-stderr.txt
Erics-MacBook-Pro:tmp redekopp$ cat foo-stderr.txt
This prints to stderr
Printing stack trace to stderr
java.lang.ArithmeticException: / by zero
at foo.main(foo.java:8)
Printing message to stderr
/ by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero
at foo.main(foo.java:16)
Erics-MacBook-Pro:tmp redekopp$ cat foo-stdout.txt
This prints to stdout
Un-caught exception will kill program and print stack trace to stderr