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 Exceptions

"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
}