可抛出参数 'ex' 到 'System.out.println()' 调用

Hif*_*ech 4 java javafx intellij-idea throwable

我目前正在研究一个库存管理系统。在系统中有注册选项,如下所示:

注册页面

以下代码显示了注册按钮方法:

        btnRegister.setOnAction(e ->{// register button method
            try {
            Stage stage = new Stage();
            FXMLLoader loader = new FXMLLoader();
            Pane root =         loader.load(getClass().getResource("Register.fxml").openStream());
            RegisterController Msg = loader.getController();
            Scene scene = new Scene(root);
            scene.getStylesheets().setAll(
                getClass().getResource("style.css").toExternalForm()
            );
            stage.setScene(scene);
            stage.show();
            ((Node) e.getSource()).getScene().getWindow().hide();

            } catch (Exception ex) {
                System.out.println(ex);
            }
        });
Run Code Online (Sandbox Code Playgroud)

我收到以下警告:

Warning:(64, 36) Throwable argument 'ex' to 'System.out.println()' call
Run Code Online (Sandbox Code Playgroud)

有人可以解释这个警告以及解决这个问题的可能方法吗?

如果被忽略,这会对以后的新更改产生任何影响吗?

它专门抱怨 register 方法中的以下代码行,其中异常是:

} catch (Exception ex) {
     System.out.println(ex);
}
Run Code Online (Sandbox Code Playgroud)

Sla*_*law 11

你应该ex.printStackTrace()改为打电话。

使用System.out.println(ex)隐藏了很多有用的、甚至可能是关键的信息。例如,如果您运行以下命令:

package com.example;

public class Main {

  public static void main(String[] args) {
    try {
      throwException();
    } catch (Exception ex) {
      System.out.println(ex);
    }
  }

  public static void throwException() throws Exception {
    throw new Exception("something went wrong");
  }
}
Run Code Online (Sandbox Code Playgroud)

您将得到以下输出:

java.lang.Exception: something went wrong
Run Code Online (Sandbox Code Playgroud)

这只告诉您异常的类型和错误消息。对于琐碎的应用程序,可能足以知道问题是什么以及问题出在哪里。但考虑一个具有数千行代码的复杂应用程序;这种异常报告不会告诉您问题发生的位置。

现在替换System.out.println(ex)ex.printStackTrace(),您将看到新的输出:

java.lang.Exception: something went wrong
    at com.example.Main.throwException(Main.java:14)
    at com.example.Main.main(Main.java:7)
Run Code Online (Sandbox Code Playgroud)

这是堆栈跟踪。从堆栈跟踪中,您可以看到执行流程,还可以看到哪一行特定的代码引发了异常。请注意,尽管您可以配置编译以放弃调试信息,这意味着您将停止获取源文件名和行号,但仍然会提供类和方法名称(总比没有好)。

它比这更进一步。Java 中的异常可能有一个原因,也可能有多个被抑制的异常。文档对此进行了更详细的描述Throwable。这是一个(人为的)示例:

package com.example;

import java.io.IOException;

public class Main {

  public static void main(String[] args) {
    try {
      throwException();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public static void throwException() throws Exception {
    IOException ioe = new IOException("could not write to stream");
    // typically suppressed exceptions come from a try-with-resources statement
    ioe.addSuppressed(new IOException("unable to close stream"));

    throw new Exception("something went wrong", ioe);
  }
}
Run Code Online (Sandbox Code Playgroud)

这给出了以下输出:

java.lang.Exception: something went wrong
    at com.example.Main.throwException(Main.java:19)
    at com.example.Main.main(Main.java:9)
Caused by: java.io.IOException: could not write to stream
    at com.example.Main.throwException(Main.java:16)
    ... 1 more
    Suppressed: java.io.IOException: unable to close stream
        at com.example.Main.throwException(Main.java:17)
        ... 1 more
Run Code Online (Sandbox Code Playgroud)

如果System.out.println(ex)使用 来代替,那么您将不会得到 或Caused by:部分Suppressed:。这意味着您不知道实际问题是什么,也不知道是否存在隐藏问题,正如您可能想象的那样,这使得解决问题变得更加困难。

System.out.println(ex)和之间还有另一个区别ex.printStackTrace()。前者打印到标准输出流(即System.out),而后者打印到标准错误流(即System.err)。由于异常是错误,因此将其打印到错误流是有意义的,但您可以通过Throwable#printStackTrace(PrintStream)或更改目标Throwable#printStackTrace(PrintWriter)。例如,ex.printStackTrace(System.out)将堆栈跟踪打印到标准输出。

最后,对于“真正的”应用程序,您可能需要使用日志记录框架。这些框架可以输出更多信息,例如报告异常的线程以及异常发生的时间戳。


查看什么是堆栈跟踪,以及如何使用它来调试应用程序错误?问答以更好地理解堆栈跟踪及其有用的原因。


Sac*_*mar 5

为了打印异常详细信息,异常类已经有一个方法名称“printStackTrace()”,

 System.out.println(ex); //not recommended 
Run Code Online (Sandbox Code Playgroud)

用这个

ex.printStackTrace();
Run Code Online (Sandbox Code Playgroud)

  • 考虑添加解释为什么不建议使用“System.out.println(ex);” (2认同)