简体   繁体   English

Eclipse为可访问代码(变体)提供死代码警告

[英]Eclipse gives dead code warning for reachable code (variant)

I have following code: 我有以下代码:

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

Eclipse gives a "dead code" warning on the return null; Eclipse在return null;给出了“死代码”警告return null; . Removing the test for keyValue == null also removes the warning but I don't see how that extra test makes the return statement dead code. 删除keyValue == null的测试也会删除警告但我没有看到额外测试如何使return语句死代码。 Clearly if the map contains no entry for some non-null keyValue , then rowIndex can still be null. 显然,如果映射不包含某些非null keyValue条目,则rowIndex仍然可以为null。 Or am I missing something here? 或者我在这里遗漏了什么?

I've seen similar Eclipse issues ( here for instance), but this one seems a different and more trivial one. 我已经看到了类似的Eclipse问题(例如这里 ),但这个问题似乎是一个不同的,更简单的问题。

The (surprising) short answer: Eclipse is right! (令人惊讶的)简短回答: Eclipse是对的! This is dead code! 这是死代码!

Reason 原因

The important part is the ternary expression in the following line of code: 重要的部分是以下代码行中的三元表达式:

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

The Java language specification (JLS) says about the "Conditional Operator ?" Java语言规范(JLS)谈到“条件运算符?” , that, if the first expression is of type int , and the second expression is of type Integer , the type of the entire expression will be int . ,如果第一个表达式是int类型,第二个表达式是Integer类型,整个表达式的类型将是int

In your case, the first expression is the constant literal value 0 , which is an int . 在您的情况下,第一个表达式是常量字面值0 ,它是一个int The second expression is the result of the get method, which returns an object of type Integer . 第二个表达式是get方法的结果,它返回一个Integer类型的对象。 So according to the JLS, the entire expression has primitive type int ! 所以根据JLS,整个表达式都有原始类型int

This means, if the second expression (the get -call) will be evaluated, the result will be unboxed from Integer to int . 这意味着,如果将计算第二个表达式( get -call),结果将从Integer取消装箱到int This int value will then be auto-boxed again into an Integer to be able to assign it to the left operand, rowIndex . 然后,此int值将再次自动装入Integer ,以便能够将其分配给左操作数rowIndex

But what happens, if the map returns a null value? 但是,如果地图返回null值,会发生什么? In this case, unboxing from Integer to int is not possible, and a NullPointerExpression will be thrown! 在这种情况下,从Integerint拆箱是不可能的,并且将抛出NullPointerExpression

So eclipse is right, as your expression can never return null , rowIndex will never be null either and the then-block of your if-statement will never be executed and hence is dead code! 所以eclipse是对的,因为你的表达式永远不会返回null ,所以rowIndex也永远不会为null ,而if语句的then-block永远不会执行,因此是死代码!

Solution

The solution is simple: Use an Integer object instead of an primitive int value for your first expression: 解决方案很简单:对第一个表达式使用Integer对象而不是原始int值:

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

My guess is that line 3 is interpreted as 我的猜测是第3行被解释为

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

(so both arguments to ?: are unified as int ) - oddly enogh, Eclipse now shows no warning, even if it is now obvious that rowIndex is never null... (所以两个参数都被统一为int ) - 奇怪的是,Eclipse现在没有显示任何警告,即使现在显然rowIndex永远不会为空...

You might also replace the 0 with Integer.valueOf(0) to make the warning disappear. 您也可以用Integer.valueOf(0)替换0以使警告消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM