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

问题描述 投票:0回答:2

我更多地是从编译器理论的角度来问这个问题。为什么空指针分析没有考虑

Assert.notNull()
的影响?

Code block show null reference access highlighted as error after 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 不进入方法调用内部进行空指针分析的理由是什么?

这只是性能问题还是有什么因素阻碍了这种做法的实现?或者使其与其他编译器检查一致(死代码分析也没有考虑该方法)?

java eclipse
2个回答
3
投票

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

因为 Eclipse 空指针分析仅考虑它正在分析的方法的语句...而不是所调用的方法的语义。 (我当然不会期望/希望 Eclipse 编译器的分析代码将

Spring
断言方法视为特殊情况。)

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

那就关闭空分析吧! (应该有一个 Eclipse 编译器首选项来执行此操作。)

或者更改您的代码,使该值不总是

null
。 或者删除取消引用
null
引用的(动态)无法访问的语句。

说实话,你的例子是如此做作,我无法想象有人会在真正的代码中做这样的事情。 没有任何“修复”不会改变代码的含义。 我想您的真实代码并非如此......


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


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

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

  • 该问题在一般情况下无法解决(停止问题),
  • 事实上,在理论上可以解决的情况下,这是一个技术上难以解决的问题,
  • 需要维护额外的代码,并且
  • 该功能的实用性“有限”。 (我认真地说,您是否真的认为值得花费许多人月来修复一小部分用户的小问题,这些用户可以在几秒钟内自行解决......通过调整编译器首选项? ) 但是如果您对此有强烈的感觉,您可以自由地开发和测试分析代码并将其贡献给 Eclipse 项目。

这当然更多的是讨论而不是问题。


0
投票

您编译时使用的 jar 不一定是您运行时使用的 jar。特别是 Assert 将成为在生产环境中进行不同实现的候选者。

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

  2. eclipse编译器在后台持续编译。因此,由于情报的代价是速度损失,因此这种检查可能更适合像

    findbugs
  3. 这样的工具。 (想想所有的库调用,通过运行时异常可能会破坏控制流。)
© www.soinside.com 2019 - 2024. All rights reserved.