【问题标题】:FindBugs doesn't find a bugFindBugs 找不到错误
【发布时间】:2012-06-07 10:04:56
【问题描述】:

我想使用 FindBugs 创建有关应用程序的报告。

我运行它并没有发现像这样的潜在错误:

public List<String> getListTrace(A object) {

    String arg = object.getArg();
    ...
}

如果对象为空,我的应用程序将关闭。

为什么 FindBugs 不发出警报?

【问题讨论】:

    标签: eclipse nullpointerexception findbugs


    【解决方案1】:

    Findbugs 不知道对象是否允许为空。你可以通过注解来判断:

    import javax.annotation.Nullable;
    ...
    public List<String> getListTrace(@Nullable A object) {
    

    这告诉 Findbugs(和阅读代码的人)可以将 null 作为参数传递给 getListTrace。因此,如果您在不检查 null 的情况下取消引用对象,Findbugs 会警告您。

    【讨论】:

      【解决方案2】:

      该代码看起来没有错误。

      如果您更改代码以检查object 是否为空,您会怎么做?最合理的操作可能是抛出NullPointerException,对吧?

      这正是您的代码 sn-p 所做的;它只是让 java 在访问方法时自动进行测试。

      这个函数不检查空指针不是错误。如果有人将空指针传递给您的函数并且没有准备好引发NullPointerException,则该错误将是。

      【讨论】:

      • 啊,好的,谢谢你的解释,我不明白这样的
      【解决方案3】:

      Findbug 无法检测到 潜在 空指针访问。但如果您在首选项中激活相应的编译器警告,Eclipse 会针对潜在的空指针访问向您发出警告。

      【讨论】:

      • 是的,但它没有在带有统计信息的报告中为我提供此信息
      • 有时候,你什么也说不出来。我为团队报告错误。我和 10 个人一起工作,所以我需要在准确的时刻制作报告以了解情况
      【解决方案4】:

      在这种情况下提出错误报告会导致非常大的噪音。您会在完全正确的代码中收到数千条不相关的错误消息。实际上 FindBugs 做了更聪明的事情。如果它发现该方法在没有空检查的情况下取消引用该参数,它会在内部将此方法参数标记为@Nonnull。如果您有与此相矛盾的显式注释(如TimK 答案),您将收到警告。否则 FindBugs 假定没有人使用此方法和可能为空的参数。当有人实际这样做时,您会在呼叫站点上收到相应的警告。这是一个例子:

      import java.util.Collections;
      import java.util.List;
      
      public class FBNull {
          static class A {
              String getArg() {
                  return "str";
              }
          }
      
          public static List<String> getListTrace(A object) {
              String arg = object.getArg();
              return Collections.singletonList(arg);
          }
      
          public void callSite(A a) {
              if (a == null) {
                  System.out.println("a is null");
              }
              System.out.println(getListTrace(a)); // NP_NULL_PARAM_DEREF 
          }
      }
      

      从 FindBugs 的观点来看,getListTrace() 方法是可以的。但是callSite 方法有一个错误。它显式地检查 null 的参数,因此由于应用程序逻辑,它可能为 null。但是,它后来被传递给getListTrace(),它立即取消引用该参数。因此,您在 getListTrace() 方法中有一个错误警告:

      Bug:在FBNull.callSite(FBNull$A) 中为getListTrace(FBNull$A) 的非空参数传递了空值

      此方法调用为非空方法参数传递空值。要么参数被注释为应该始终为非空的参数,要么分析表明它将始终被取消引用。

      因此,如果您确实可以传递空值,则可以在调用站点上检测到它。

      【讨论】:

        猜你喜欢
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-30
        • 1970-01-01
        • 2011-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多