Java - 在不允许使用@NotNull或@Nullable注释时在编译时检测NPE的最佳方法

Pro*_*tle 16 java null nullpointerexception

我曾经使用大量的@NotNull/@Nullable注释来使IDE能够帮助我NPE在编译时找到潜力.但是,我的新团队不允许使用任何@NotNull/@Nullable注释,也不允许使用自定义注释.结果,我变得更容易写出NPE比以前造成的错误.

我尝试了几种解决方案:

  1. Optional<T>在java 8中使用.但是,这并不适用于所有情况.通常不建议将其Optional<T>用作字段或参数的类型.Optional<T>实例本身也是非常令人沮丧的null.此外,在调用时很难在lambda表达式中操作控制流ifPresent(obj->...)(在Java 9中更容易).并且使用太多Optional<T>s会使代码变得有点冗长.(更新:不幸的是,Optional<T>现在也被禁止使用)
  2. 让IDE将每个未注释的实例视为@Nullable.这个解决方案确实可以帮助我发现一些潜在的错误,但是,IDE会建议我检查几乎每个方法调用,这真的很烦人,因为很多方法都是故意设计不返回的null.
  3. 检查每个方法调用.这是一个可行的解决方案,但是它具有严重的影响,即null通过方法调用将可能传播到任何地方.在这种情况下,方法的每个参数都是可能的null,并且当检查参数是否为null时,该方法通常会null连续返回.最后,每个方法都被"感染",有可能接收null参数并返回null.
  4. 打电话Objects.requireNonNull()来防止上述问题.它略微减少了null到处检查的痛苦.但是,它不保证调用者null在null不允许的情况下不会传递给案例.一旦null通过,NPE抛出的运行时更可能破坏您的应用程序.
  5. 切换到kotlin.当然,不允许:)

有关于在编译时检测NPE(并保存我的工作)的其他建议吗?我认为这个问题的解决方案可以被广泛使用,不仅可以帮助自己,因为并非所有团队都允许使用@NotNull/@Nullable注释和Optional<T>s.

Alg*_*giz 9

不是一个明确的答案,而是一些探索方式:

  • findBug,PMD,Coverity等工具在这方面非常擅长.
  • 检查您无法在团队中使用注释的原因.也许你可以让你的团队改变主意?(也可能有一个很好的理由.)
  • Eclipse IDE在这方面非常擅长.您是否尝试过"Windows>首选项> Java>编译器>错误/警告>空分析"中的选项?
  • 单元测试.在一些测试用例中涵盖"应该不会发生"的情况.代码覆盖工具(如JaCoCo)可能也会有所帮助.
  • 防御性编程(简单'如果'声明,断言......)
  • 混合以前的项目

希望这可以帮助.


Far*_*ron 5

你没有说你正在使用什么IDE,但Eclipse和Intellij支持外部注释。有了它们,您仍然可以在本地注释代码并让 IDE 提供 null 分析。

Intellij 文档
Eclipse 文档