【问题标题】:condition to avoid NPE for nested exceptions when using getCause().getCause() [closed]使用 getCause().getCause() 时避免 NPE 嵌套异常的条件 [关闭]
【发布时间】:2020-01-06 22:14:40
【问题描述】:

我正在处理 java 中的嵌套异常,我想使用条件(例如 if(t.getCause().getCause() instanceOf MyCustomException))检查我的自定义异常的类型,但这可能会引发潜在的 NPE。

所以我打算使用以下条件检查 null

if(t.getCause().getCause() != null) 
&& t.getCause().getCause() instanceOf MyCustomException) {
   ..........
}

这是一个好方法吗。如果有更好的方法,请建议我?

谢谢!

【问题讨论】:

    标签: java if-statement exception try-catch


    【解决方案1】:

    您提出的代码很脆弱。如果您更改了嵌套,if 将会中断。更好的模式是在因果链上编写通用搜索:

    @SuppressWarning("unchecked")
    public static <T> T getFirstCause(Throwable ex, Class<T> exClass) {
      for (Throwable cause = ex; cause != null; cause = cause.getCause()) {
        if (exClass.isAssignableFrom(cause)) {
          // Unchecked by Java type system, but verified by the if above.
          return (T) cause;
        }
      }
      return null;
    }
    

    现在你说

    if (getFirstCause(t, myCustomeException.class) != null) {
       ...
    }
    

    如果需要,您还可以检索匹配的实例。

    myCustomeException customEx = getFirstCause(t, myCustomeException.class);
    if (customEx != null) {
       OtherInfo info = customEx.getCustomeExInfo()
    }
    

    【讨论】:

      【解决方案2】:

      如果我见过的最好的方法类似于

      Throwable anException = t.getCause();
      while(anException != null){
           // Do a thing with with the throwable.
           anException = anException.getCause();
      }
      

      我没有测试它,但你应该明白了!

      【讨论】:

        【解决方案3】:

        instanceOf不会导致NullPointerException

        JLS 15.20.2. Type Comparison Operator instanceof 说:

        如果 RelationalExpression 不是 null 的值,则 instanceof 运算符的结果是 true,并且可以将引用转换为 ReferenceType 没有提出ClassCastException。否则结果为false

        现在,first getCause() 可以返回 null,使得 second 调用导致 NPE,因此您的代码应该是:

        if (t.getCause() != null
         && t.getCause().getCause() instanceOf myCustomeException) {
           ..........
        }
        

        这假定t 本身不能为空。

        【讨论】:

          【解决方案4】:

          您的方法不会按照您的计划进行。让我解释一下原因:

          1. 当您使用 instanceof 时,您已经在检查对象是否为 null(例如 null 不是 instanceof myCustomerException,所以它是 false)
          2. 如果您已经在使用instanceof,则意味着您的问题不在t.getCause().getCause(),而可能在t.getCause() 甚至t

          我建议你有一个方法来为你做检查,所以你做一个干净的电话。比如:

          public boolean isTheNestedException(Throwable t) { // Assuming you are using throwable
              return t != null && t.getCause() != null && t.getCause().getCause() instanceof MyCustomerException; // Assuming your "MyCustomerException" is a custom exception class
          }
          

          你会像这样使用它:

          if (isTheNestedException(t) {
              ....
          }
          

          【讨论】:

            【解决方案5】:

            首先,您没有检查 tt.getCause() 本身 (t != null &amp;&amp; t.getCause() != null)。第二个错误在这里:x instanceOf myCustomeException

            其次,除非myCustomeException 是一个类(在这种情况下,它应该按照标准规定为大写),这是一种无效的语法。在instanceof 之后需要一个类名。

            P.S.:这是来自您的 ide 的警告,因此如果您确定它们不会为 null 并且不想要额外的、不必要的代码,您可以使用 @SuppressWarnings("unchecked") 禁止警告。

            【讨论】:

            • 你是对的,MyCustomException 是我的自定义异常类名,我刚刚编辑了我的问题。谢谢
            猜你喜欢
            • 2018-11-04
            • 2019-01-10
            • 2015-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-26
            • 1970-01-01
            相关资源
            最近更新 更多