2017-07-19 43 views
2

检查时,认识到自定义的断言我有下面的一段Java代码:如何配置Eclipse(Java)的对抗潜在的空指针

public void silence(final Object key) { 
    final Chain chain = (Chain)getChain(key); 
    checkPrecondition(chain != null); 
    chain.silence(); 
    } 

的checkPrecondition调用产生了一个运行时异常,如果链为空,但是Eclipse似乎没有“得到这个”:它说chain.silence()是一个可能的空指针访问(警告)。 问题:如何“告诉”Eclipse,checkPrecondition()确保链不为空,即具有断言的性质?我知道我可以禁用此警告,但我宁愿不这样做,因为在其他情况下,这可能是合理的。有趣的是,当我删除checkPrecondition()调用时,警告消失了(这正是我期望看到的情况)。

我在Windows上使用Eclipse 4.4.2(32位)。 Java VM是1.3(!)。更新到较新版本的任何一个目前都不是一种选择。

+0

无关:因为您担心代码质量......请考虑一下,如果您真的想遵循那种在所有地方都放置“最终”的丑陋方法。使链最终为此方法增加*零*值。这只是线路噪声,没有真正的目的。 – GhostCat

+0

在这种情况下,“最终”的使用无可否认地限制了收益,但也没有成本。所以完全没有损失。在其他上下文中,“final”的使用传达了程序员的意图,并且可能导致在编译时检测到编码错误,而不是通过繁琐的测试。我们的编码准则明确要求使用“最终”,所以我所见过的最现代和严格的编码准则也是如此。非常高的好处! – FreeSpirit64

+0

因此,Java语言的人们花费宝贵的时间来改进编译器,以便有效地检测**最终变量 - 这样您就不必为事后未更改的局部变量写下最终的变量;-)。 ..当你让我好奇:你能给一些例子链接? – GhostCat

回答

0

您不告诉Eclipse,您必须以Java语言编译器将成功编译并且JVM能够执行的语法和逻辑生成代码。

发生运行时异常是正常的。变量值只能在运行时检查,对于空指针也是如此(事实上,几乎所有语言都假装来自C并且使用与指针相关的东西,C之前就是这种情况)。

您可以使用两种不同的方法来解决此问题,具体取决于您的风格以及您的projet中使用的风格。

  • 首先是在defensing方式 - >您认为发生这样的错误之前子程序 人都被杀害(空指针错误 耗费了大量的软件业)。

    public void silence(final Object key) { 
    
        if (key == null) { 
         throw new IllegalArgumentException("Key should not be null."); 
        } 
    
        Object oChain = getChain(key); 
    
        if (oChain == null || !(oChain instanceof Chain)) { 
         throw new IllegalArgumentException("Key should be mapped to an object from the Chain class type."); 
        } 
    
        Chain chain = (Chain)oChain; 
        if(checkPrecondition(chain)) { 
         chain.silence(); 
        } 
    } 
    
  • 第二种方式是进攻:调用代码应对此进行处理和子进程没有崩溃的东西!

    public boolean silence(final Object key) { 
        if (key == null) return false; 
        Object oChain = getChain(key); 
        if (oChain == null || !(oChain instanceof Chain)) return false; 
        Chain chain = (Chain)oChain; 
        if(!checkPrecondition(chain)) return false; 
        chain.silence(); 
        return true; 
    } 
    

请注意,我假设校验条件方法返回一个布尔值,而且其单个参数应该是从连锁类的对象。

+0

我很感谢您花时间回复,非常感谢。但是,我并没有真正看到我的问题的答案。问题在于,在调用checkPrecondition()调用时,即使没有问题(处理空例),Eclipse也会抱怨。由于调用不到位,**有**问题(空案**未处理),但Eclipse不会投诉。在我们的例子中,增加代码大小基本上是每个以上都不是一种选择。另一方面,你的提示不仅要检查null,还要检查“instanceof”。 – FreeSpirit64

+0

我的意思是“告诉Eclipse”是这样的:例如,PC lint允许我声明某个自定义表达式就像一个断言,并且在静态代码分析过程中应被视为“断言”的同义词。这非常有意义,这正是我在Eclipse中寻找的。 – FreeSpirit64

+0

随着我的版本:没有抱怨。那么我明白你很困惑,但你的代码似乎并没有编译(尤其是* checkPrecondition *调用,因为你传递了一个布尔型,其他类型正在等待,至少我希望如此)。通常情况下,您只是不尝试修改Eclipse Linter,这可能是您将获得的最大帮助之一(后面的人是非常优秀的程序员,您可以信任他们)。如果你这样做,你不再需要Eclipse了。更新代码比修改Eclipse本身更简单:想象修改Linter每次更新或项目中新到达的内容。 –