简体   繁体   中英

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; . 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. Clearly if the map contains no entry for some non-null keyValue , then rowIndex can still be 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.

The (surprising) short answer: Eclipse is right! 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 ?" , 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 .

In your case, the first expression is the constant literal value 0 , which is an int . The second expression is the result of the get method, which returns an object of type Integer . So according to the JLS, the entire expression has primitive type int !

This means, if the second expression (the get -call) will be evaluated, the result will be unboxed from Integer to int . This int value will then be auto-boxed again into an Integer to be able to assign it to the left operand, rowIndex .

But what happens, if the map returns a null value? In this case, unboxing from Integer to int is not possible, and a NullPointerExpression will be thrown!

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!

Solution

The solution is simple: Use an Integer object instead of an primitive int value for your first expression:

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

My guess is that line 3 is interpreted as

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...

You might also replace the 0 with Integer.valueOf(0) to make the warning disappear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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