它不应该是

它不应该是

问题描述:

我有一个非常简单的Java代码,这样的(这仅仅是一个节选)死代码警告:它不应该是

for(;;) 
{ 
    AnObject object = null; 
    for(AnObject elem : list) // where the list is of the type List<AnObject> 
    { 
    if(<some dynamic condition goes here>) 
    { 
     object = elem; 
    } 
    } 

    Log.v(TAG, object.property); // was initially omitted, added for the answer 

    // more code skipped for simplicity 

    if(object == null) 
    {     // 
    break;   // 
    }     // this all is marked as dead code 
} 

在Eclipse中,有意见的片段被标记为死代码。为什么?条件中没有final元素。 object变量没有被分配到常量空值的任何地方,除了循环的最开始,在此之后它应该通常被覆盖,但它不会总是发生。 object可以很好地为空和非空。

我错过了什么吗?

答案

嗯,我找到了答案,并显示出它,我必须一行代码添加到我的例子,试图简化代码片段时,我偶然忽略,但它是重要。该行是:

Log.v(TAG, object.property); 

所以对象必须是非空的,否则代码无法通过例外得到。这行是为了调试而临时添加的,这就是为什么它不在我的考虑之列。

+5

发布证明您的问题的SSCCE。 – 2012-07-11 14:29:40

+0

@MarkoTopolnik,嗯,这可能需要一段时间准备。 – Stan 2012-07-11 14:30:55

+0

你现在展示的东西没有证明问题。我不知道现在有人能帮助你。 – 2012-07-11 14:31:44

我不能在eclipse中重现那个警告。

难道是你无意中忘记了原始问题中的一些代码,这可能会导致无法执行代码的情况。当您将完整的if语句标记为死代码而不仅仅是它的正文时,这似乎就是这种情况。缺少的行可能是实际使用object(可能与您尝试访问object的属性之一的日志语句一样简单)。

即使if条件没有标记为死亡,它的身体可能仍然是。 object不是null(并且if正文将不会执行)或者 - 如果object为空 - 将在该缺失的行中引发NullPointerException,以便执行在那里停止。

+0

我很奇怪,如果编译器发现对象不能为null,否则代码会在上面的日志行中引发空指针异常,为什么它没有将日志行标记为危险? – Stan 2012-07-17 18:00:37

+0

'NullPointerException' [unchecked](http://docs.oracle.com/javase/specs/jls/se7/html/jls-11.html),所以Eclipse唯一抱怨的是无法访问的代码。如果你的代码确保'object'不是'null',这是编译器“假定”的东西,那么这行并不是那么危险。 – Wolfram 2012-07-17 19:00:19

+0

感谢您的澄清,但不清楚为什么具有'object.property'的行让编译器假定对象不是'null'。你可以点亮一下吗?我有点困惑。 – Stan 2012-07-17 20:10:12

不能与下面的程序重现:

​​

这就是Eclipse 3.7.2与Java SE 1.7

因为,如果列表为空(在你的代码有一个为列表中没有的init ),你将不会初始化Object。 我的悲伤,我的坏。

如果内部'if'始终为false,则可以在内部标记死码。 如果元素为空,最后的比较仍然适用。 如果您在死代码块之前返回,它将引发无法访问的代码错误。

正如其他人所说,无法复制它。

+0

请参阅下面的程序:使用'List = null'它仍然不会在Eclipse 3.7.2中显示死代码 – Martijn 2012-07-11 14:38:16

+0

嗯,这是因为eclipse在foreach中引发了警告(在foreach中的空指针访问警告列表中) – Alfabravo 2012-07-11 14:41:08

+0

是的,它的确如此。它仍不会显示OP中描述的行为:指定部分的死代码。 – Martijn 2012-07-11 14:42:17