Eclipse针对可用的代码(变体)发出无效代码警告

时间:2018-10-15 10:08:53

标签: java eclipse dead-code

我有以下代码:

public String myMethod(String keyValue) {
    Map<String, Integer> keyValueToRowIndex = ...
    Integer rowIndex = (keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue);
    if (rowIndex == null)
      return null;
    ...
}

Eclipse在return null;上发出“死代码”警告。删除keyValue == null的测试也可以删除警告,但是我看不到额外的测试如何使return语句变为无效代码。显然,如果映射不包含某些非空keyValue的条目,则rowIndex仍可以为null。还是我在这里想念什么?

我见过类似的Eclipse问题(例如,here),但这似乎是一个不同且更琐碎的问题。

2 个答案:

答案 0 :(得分:3)

(令人惊讶的)简短答案: Eclipse是对的!这是无效代码!

原因

重要的部分是以下代码行中的三元表达式:

    Integer rowIndex = (keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue);

Java language specification (JLS)说起"Conditional Operator ?",如果第一个表达式的类型为int,第二个表达式的类型为Integer,则{整个表达式将为int

在您的情况下,第一个表达式是常量文字值0,它是int。第二个表达式是get方法的结果,该方法返回类型为Integer的对象。因此,根据JLS,整个表达式具有原始类型int

这意味着,如果将对第二个表达式(get-调用)求值,则结果将从Integerint取消装箱。然后,此int值将再次自动装箱到Integer中,以便能够将其分配给左侧的操作数rowIndex

但是,如果映射返回一个null值,会发生什么?在这种情况下,无法从Integerint拆箱,并且会抛出NullPointerExpression

因此,月食是正确的,因为您的表达式永远不会返回nullrowIndex也永远不会null,并且if语句的then块也不会执行,因此是无效代码!

解决方案

解决方案很简单:在第一个表达式中使用Integer对象而不是原始的int值:

Integer rowIndex = (keyValue == null) ? Integer.valueOf(0) : keyValueToRowIndex.get(keyValue);

答案 1 :(得分:1)

我的猜测是第3行被解释为

Integer rowIndex = Integer.valueOf((keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue).intValue());

(所以?:的两个参数都统一为int)-奇怪的是,Eclipse现在没有显示警告,即使现在很明显rowIndex从不为空...

您也可以将0替换为Integer.valueOf(0),以使警告消失。