我有以下代码:
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
仍然可以为空。还是我在这里错过了什么?
我见过类似的Eclipse问题(例如在这里(,但这个问题似乎是一个不同的,更微不足道的问题。
(令人惊讶的(简短回答:Eclipse 是对的!这是死代码!
原因
重要的部分是以下代码行中的三元表达式:
Integer rowIndex = (keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue);
Java 语言规范 (JLS( 关于"条件运算符?",如果第一个表达式的类型是int
,而第二个表达式是类型Integer
,则整个表达式的类型将被int
。
在您的情况下,第一个表达式是常量文本值0
,这是一个int
。第二个表达式是get
方法的结果,该方法返回类型为Integer
的对象。所以根据 JLS,整个表达式都有基元类型int
!
这意味着,如果将计算第二个表达式(get
-call(,则结果将从Integer
到int
取消装箱。然后,此int
值将再次自动装箱到Integer
中,以便能够将其分配给左操作数rowIndex
。
但是,如果映射返回null
值,会发生什么情况?在这种情况下,从Integer
拆箱到int
是不可能的,并且会扔NullPointerExpression
!
所以 eclipse 是对的,因为你的表达式永远不会返回null
,rowIndex
也永远不会null
,你的 if 语句的 then-block 永远不会被执行,因此是死代码!
溶液
解决方案很简单:对第一个表达式使用Integer
对象而不是基元int
值:
Integer rowIndex = (keyValue == null) ? Integer.valueOf(0) : keyValueToRowIndex.get(keyValue);
我的猜测是第 3 行被解释为
Integer rowIndex = Integer.valueOf((keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue).intValue());
(所以两个参数 ?: 都统一为int
( - 奇怪的是,Eclipse 现在没有显示任何警告,即使现在很明显 rowIndex 永远不会为空......
您还可以将0
替换为Integer.valueOf(0)
以使警告消失。