Throwable 参数 'ex' 到 'System.out.println()' 调用
Throwable argument 'ex' to 'System.out.println()' call
我目前正在研究库存管理系统。在系统中有如下所示的注册选项:
以下代码显示注册按钮方法:
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);
}
});
我收到以下警告:
Warning:(64, 36) Throwable argument 'ex' to 'System.out.println()' call
有人可以解释这个警告和可能的解决方法吗?
如果忽略这对以后的新更改会有任何影响吗?
它特别抱怨注册方法中的以下代码行,异常是:
} catch (Exception ex) {
System.out.println(ex);
}
为了打印异常的详细信息,Exception class 已经有一个方法名 "printStackTrace()",
System.out.println(ex); //not recommended
使用这个
ex.printStackTrace();
你应该打电话给 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");
}
}
您得到以下输出:
java.lang.Exception: something went wrong
那只会告诉你异常的类型和错误信息。对于可能足以知道问题所在和位置的琐碎应用程序。但是考虑一个包含数千行代码的复杂应用程序;这种异常报告告诉您没有关于问题发生的地方。
现在将 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)
这是堆栈跟踪。从堆栈跟踪中,您可以看到执行流程,还可以看到具体的代码行引发了异常。请注意,尽管您可以将编译配置为丢弃调试信息,这意味着您将停止获取源文件名和行号,但仍会为您提供 class 和方法名称(总比没有好)。
它比这更进一步。 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);
}
}
这给出了以下输出:
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
如果使用 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)
会将堆栈跟踪打印到标准输出。
最后,对于 "real" 应用程序,您可能需要使用日志记录框架。这些框架可以输出更多信息,例如报告异常的线程以及何时发生异常的时间戳。
查看 What is a stack trace, and how can I use it to debug my application errors? 问答以更好地理解堆栈跟踪及其有用的原因。
我目前正在研究库存管理系统。在系统中有如下所示的注册选项:
以下代码显示注册按钮方法:
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);
}
});
我收到以下警告:
Warning:(64, 36) Throwable argument 'ex' to 'System.out.println()' call
有人可以解释这个警告和可能的解决方法吗?
如果忽略这对以后的新更改会有任何影响吗?
它特别抱怨注册方法中的以下代码行,异常是:
} catch (Exception ex) {
System.out.println(ex);
}
为了打印异常的详细信息,Exception class 已经有一个方法名 "printStackTrace()",
System.out.println(ex); //not recommended
使用这个
ex.printStackTrace();
你应该打电话给 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");
}
}
您得到以下输出:
java.lang.Exception: something went wrong
那只会告诉你异常的类型和错误信息。对于可能足以知道问题所在和位置的琐碎应用程序。但是考虑一个包含数千行代码的复杂应用程序;这种异常报告告诉您没有关于问题发生的地方。
现在将 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)
这是堆栈跟踪。从堆栈跟踪中,您可以看到执行流程,还可以看到具体的代码行引发了异常。请注意,尽管您可以将编译配置为丢弃调试信息,这意味着您将停止获取源文件名和行号,但仍会为您提供 class 和方法名称(总比没有好)。
它比这更进一步。 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);
}
}
这给出了以下输出:
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
如果使用 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)
会将堆栈跟踪打印到标准输出。
最后,对于 "real" 应用程序,您可能需要使用日志记录框架。这些框架可以输出更多信息,例如报告异常的线程以及何时发生异常的时间戳。
查看 What is a stack trace, and how can I use it to debug my application errors? 问答以更好地理解堆栈跟踪及其有用的原因。