Eclipse выдает предупреждение о мертвом коде для достижимого кода (вариант) - PullRequest
0 голосов
/ 15 октября 2018

У меня есть следующий код:

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 также удаляет предупреждение, но я не вижу, как этот дополнительный тест делает оператор возврата мертвым кодом.Ясно, что если на карте нет записи для некоторого ненулевого keyValue, то rowIndex все еще может быть нулевым.Или я что-то здесь упускаю?

Я видел похожие проблемы с Eclipse (например, здесь ), но эта кажется другой и более тривиальной.

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

(Удивительно) краткий ответ: Затмение верно!Это мертвый код!

Причина

Важной частью является троичное выражение в следующей строке кода:

    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!

Итак, затмение верно, поскольку ваше выражение никогда не сможет вернуть null, rowIndexтакже никогда не будет null, а блок then вашего оператора if никогда не будет выполнен и, следовательно, является мертвым кодом!

Решение

Решение простое: Используйте объект Integer вместо примитивного значения int для вашего первого выражения:

Integer rowIndex = (keyValue == null) ? Integer.valueOf(0) : keyValueToRowIndex.get(keyValue);
0 голосов
/ 15 октября 2018

Я предполагаю, что строка 3 интерпретируется как

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

(так что оба аргумента?: Объединены как int) - как ни странно, Eclipse теперь не показывает предупреждение, даже если оно сейчасочевидно, что rowIndex никогда не бывает нулевым ...

Вы также можете заменить 0 на Integer.valueOf(0), чтобы предупреждение исчезло.

...