我有以下代码:
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),但这似乎是一个不同且更琐碎的问题。
答案 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
-调用)求值,则结果将从Integer
到int
取消装箱。然后,此int
值将再次自动装箱到Integer
中,以便能够将其分配给左侧的操作数rowIndex
。
但是,如果映射返回一个null
值,会发生什么?在这种情况下,无法从Integer
到int
拆箱,并且会抛出NullPointerExpression
!
因此,月食是正确的,因为您的表达式永远不会返回null
,rowIndex
也永远不会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)
,以使警告消失。