0

我更多地从编译器理论的角度提出这个问题。为什么空指针分析没有考虑效果Assert.notNull()

代码块显示空引用访问在 Assert.notNull() 之后突出显示为错误

Assert 方法来自 Spring,它被实现为:

public static void notNull(Object object, String message) {
    if (object == null) {
        throw new IllegalArgumentException(message);
    }
}

public static void notNull(Object object) {
    notNull(object, "[Assertion failed] - this argument is required; it must not be null");
}

(这变得很烦人,因为如果我使用这种断言实用程序,在断言之后第一次访问该变量会导致警告,这会阻止我实现无警告代码。)

如果我完全内联断言例程,访问a将不会被标记为空指针访问(在这种微不足道的情况下,它将成为死代码)。但是,静态方法不能被覆盖(不是没有字节码摆弄),那么编译器设计者的 POV 不进入方法调用以进行空指针分析的理由是什么?

它只是性能问题还是有什么东西阻止了这一切?或者使其与其他编译器检查一致(死代码分析也没有考虑该方法)?

4

2 回答 2

3

为什么 Eclipse 空指针分析无法识别断言实用程序?

因为 Eclipse 空指针分析只考虑它正在分析的方法的语句......而不是被调用的方法的语义。(而且我当然不希望/希望 Eclipse 编译器的分析代码将Spring断言方法视为一种特殊情况。)

这变得很烦人......

那么关闭空分析!(应该有一个 Eclipse 编译器偏好来执行此操作。)

或者更改您的代码,使该值不总是null. 或者删除取消引用引用的(动态)不可达语句null

老实说,你的例子太做作了,我无法想象有人在真实的代码中做这样的事情。没有不会改变代码含义的“修复”。我想这不是你的真实代码的情况......


仔细想想,这里的问题大致相当于Java中检测未初始化变量和不可达语句的问题。Eclipse 正在采用与 Java/JLS 相同的解决方案。


至于 Eclipse应该使用最先进的非本地分析代码的想法......我不同意。它会使 Eclipse 的交互式编译像糖浆一样慢。

不执行此操作还有其他原因,包括:

  • 在一般情况下无法解决问题的事实(停止问题),
  • 在理论上可以解决的情况下,这是一个技术上难以解决的问题,
  • 需要维护额外代码的事实,以及
  • 该功能的实用性有限的事实。(我的意思是说真的,你真的认为值得花很多人月来解决一小部分用户的小问题,这些用户可以在几秒钟内自己解决......通过调整编译器偏好?)

但是,如果您对此有强烈的感觉,您可以自由地开发和测试分析代码并将其贡献给 Eclipse 项目。

于 2012-12-10T00:43:57.597 回答
0

这当然是一个讨论而不是一个问题。

  1. 你编译的jar不一定是你运行的jar。特别是 Assert 将成为在生产环境中具有不同实现的候选者。

  2. 空指针错误会比死代码错误更好(此处)。

  3. eclipse编译器在后台连续编译。因此,由于智能是以速度损失为代价的,因此这种检查可能更适用于findbugs之类的工具。(想想所有的库调用,通过运行时异常可能会破坏控制流。)

于 2012-12-10T00:54:51.203 回答