Java 中的异常处理有 Java 个最佳实践
Exception Handling in Java to have Java best practices
我有一个 Java 方法,如下所示:
private boolean getBooleanProperty(String property, String defaultValue) {
boolean result = false;
try {
result = Boolean.parseBoolean(properties.getProperty(property, defaultValue));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
我知道我在上述方法中处理异常的方式不正确,正在寻找使这些方法更符合 Java 标准和最佳实践的方法。
与以下方法类似:
public void getStatusAndAnnotation(ITestResult result) {
try {
HashMap<Object, Object> map = new HashMap<>();
Method method = result.getMethod().getConstructorOrMethod().getMethod();
TestInfo annotation = method.getAnnotation(TestInfo.class);
try {
//add id removing the first character of the annotation (e.g. for C12034, send 12034)
if(annotation!=null) {
map.put("id",annotation.id().substring(1));
}
}catch (NullPointerException e){
e.printStackTrace();
}
if (result.getStatus() == ITestResult.SUCCESS) {
map.put("result", 1);
} else if (result.getStatus() == ITestResult.FAILURE) {
map.put("result", 9);
} else if (result.getStatus() == ITestResult.SKIP) {
map.put("result", 10);
}
if (annotation != null) {
if(annotation.trDeploy() && !map.get("id").equals(null) && !map.get("id").toString().isEmpty())
{
ApiIntegration.addTestResult(map);
}
else System.out.println("Deploying result was canceled, because test has annotation \"trDeploy: false\" or \"id\" has no value");
}
} catch (SecurityException | IOException
| ApiException | NullPointerException e) {
e.printStackTrace();
}
}
如何处理这些不同的异常以符合最佳实践?
我通常做的是让 compiler/IDE 告诉我需要捕获哪些异常,除非您出于特定原因想要捕获异常。这样,我可以在不捕获不必要的异常的情况下编写代码,并且我的代码更清晰。
这些类型的异常称为 Checked Exceptions
"In the Java class hierarchy, an exception is a checked exception if
it inherits from java.lang.Exception, but not from
java.lang.RuntimeException. All the application or business logic
exceptions should be checked exceptions."
例子:
try
{
// open a file (Compiler will force to either catch or throw)
}
catch (IOException ioe)
{
ioe.printStackTrace();
// need to make a decision on what to do here
// log it, wrap it in a RuntimeException, etc.
}
"Unchecked, uncaught or runtime exceptions are exceptions that can be
thrown without being caught or declared"
例子:
String x = null;
// this will throw a NullPointerException
// However, you don't need to catch it as stated in some the comments
x.toString();
你应该做的是预防它
if (x == null)
{
x = "some default value"; // prevent the exception from happening.
}
x.toString();
这是否意味着您永远不应该捕获 RuntimeException
不,当然不是。这取决于场景。
举个例子:
String number = "12345";
// You don't know if number is a valid integer until you parse it
// If the string is not a valid number, then this code will
// throw an Exception
int i = Integer.parseInt(number);
相反,您可以捕获 NumberFormatException。同样,这是 预防.
的一种形式
int i = 0; // some default
try
{
i = Integer.parseInt(number);
}
catch (NumberFormatException nfe)
{
// Good practice to log this, but the default int is fine.
}
一些最佳实践
- 不要捕获异常,除非编译器强制您这样做。
- 如果您正在捕获已检查的异常,请将其记录下来。如果您希望它渗入调用堆栈,您也可以将其包装在 RuntimeException 中。
- 如果你想捕获一个 RuntimeException,那么这样做是有目的的(即你可以设置一个默认值并一起防止错误。)
- 没有一连串的方法都在堆栈跟踪中抛出已检查的异常。这非常混乱,并强制所有调用方法捕获或抛出已检查的异常。
- 捕获 RuntimeException 只是为了记录它确实没有太大的目的。除非您将其记录在捕获所有位置。
包罗万象的例子:
try
{
// entry point to application
}
catch (Throwable t)
{
// let all exceptions come here to log them
}
我有一个 Java 方法,如下所示:
private boolean getBooleanProperty(String property, String defaultValue) {
boolean result = false;
try {
result = Boolean.parseBoolean(properties.getProperty(property, defaultValue));
} catch (IllegalArgumentException | NullPointerException e) {
}
return result;
}
我知道我在上述方法中处理异常的方式不正确,正在寻找使这些方法更符合 Java 标准和最佳实践的方法。
与以下方法类似:
public void getStatusAndAnnotation(ITestResult result) {
try {
HashMap<Object, Object> map = new HashMap<>();
Method method = result.getMethod().getConstructorOrMethod().getMethod();
TestInfo annotation = method.getAnnotation(TestInfo.class);
try {
//add id removing the first character of the annotation (e.g. for C12034, send 12034)
if(annotation!=null) {
map.put("id",annotation.id().substring(1));
}
}catch (NullPointerException e){
e.printStackTrace();
}
if (result.getStatus() == ITestResult.SUCCESS) {
map.put("result", 1);
} else if (result.getStatus() == ITestResult.FAILURE) {
map.put("result", 9);
} else if (result.getStatus() == ITestResult.SKIP) {
map.put("result", 10);
}
if (annotation != null) {
if(annotation.trDeploy() && !map.get("id").equals(null) && !map.get("id").toString().isEmpty())
{
ApiIntegration.addTestResult(map);
}
else System.out.println("Deploying result was canceled, because test has annotation \"trDeploy: false\" or \"id\" has no value");
}
} catch (SecurityException | IOException
| ApiException | NullPointerException e) {
e.printStackTrace();
}
}
如何处理这些不同的异常以符合最佳实践?
我通常做的是让 compiler/IDE 告诉我需要捕获哪些异常,除非您出于特定原因想要捕获异常。这样,我可以在不捕获不必要的异常的情况下编写代码,并且我的代码更清晰。
这些类型的异常称为 Checked Exceptions
"In the Java class hierarchy, an exception is a checked exception if it inherits from java.lang.Exception, but not from java.lang.RuntimeException. All the application or business logic exceptions should be checked exceptions."
例子:
try
{
// open a file (Compiler will force to either catch or throw)
}
catch (IOException ioe)
{
ioe.printStackTrace();
// need to make a decision on what to do here
// log it, wrap it in a RuntimeException, etc.
}
"Unchecked, uncaught or runtime exceptions are exceptions that can be thrown without being caught or declared"
例子:
String x = null;
// this will throw a NullPointerException
// However, you don't need to catch it as stated in some the comments
x.toString();
你应该做的是预防它
if (x == null)
{
x = "some default value"; // prevent the exception from happening.
}
x.toString();
这是否意味着您永远不应该捕获 RuntimeException
不,当然不是。这取决于场景。
举个例子:
String number = "12345";
// You don't know if number is a valid integer until you parse it
// If the string is not a valid number, then this code will
// throw an Exception
int i = Integer.parseInt(number);
相反,您可以捕获 NumberFormatException。同样,这是 预防.
的一种形式int i = 0; // some default
try
{
i = Integer.parseInt(number);
}
catch (NumberFormatException nfe)
{
// Good practice to log this, but the default int is fine.
}
一些最佳实践
- 不要捕获异常,除非编译器强制您这样做。
- 如果您正在捕获已检查的异常,请将其记录下来。如果您希望它渗入调用堆栈,您也可以将其包装在 RuntimeException 中。
- 如果你想捕获一个 RuntimeException,那么这样做是有目的的(即你可以设置一个默认值并一起防止错误。)
- 没有一连串的方法都在堆栈跟踪中抛出已检查的异常。这非常混乱,并强制所有调用方法捕获或抛出已检查的异常。
- 捕获 RuntimeException 只是为了记录它确实没有太大的目的。除非您将其记录在捕获所有位置。
包罗万象的例子:
try
{
// entry point to application
}
catch (Throwable t)
{
// let all exceptions come here to log them
}