Как я могу обнаружить мертвый код после всегда бросающих методов?

рассмотрите следующий код:

@Test 
public void testDeadCode() {
    letsThrow();
    System.out.println("will never be reached");
}

private final void letsThrow() {
    throw new RuntimeException("guess you didnt see this one coming");
}

Мне кажется абсолютно невозможным, чтобы println () когда-либо выполнялся - так как вызов функции letThrow () всегда вызывает исключение.

Таким образом, я

а) удивлен, что компилятор не может сказать мне "это мертвый код"

б) интересно, есть ли какие-нибудь флаги компилятора (или настройки затмения), которые привели бы к тому, что я сказал: у вас там мертвый код.

7 голосов | спросил GhostCat 8 J0000006Europe/Moscow 2016, 17:34:01

3 ответа


0

Ошибки времени компиляции мертвого кода определяются компилятором, а не IDE. Хотя это правда, что код никогда не будет выполнен, он не нарушает никаких правил для недостижимых операторов из Документов Oracle.

Из недоступных заявлений

  

Этот раздел посвящен точному объяснению слова «достижимый». Идея состоит в том, что должен существовать некоторый возможный путь выполнения от начала конструктора, метода, инициализатора экземпляра или статического инициализатора, который содержит инструкцию к самой инструкции. Анализ учитывает структуру высказываний. За исключением специальной обработки while, do и операторов, выражение условия которых имеет постоянное значение true, значения выражений не учитываются в анализе потока.

Правила, специально предназначенные для этого случая, связаны с тем, доступны ли созданные вами блоки. (если только тогда и только тогда)

  

Пустой блок, который не является блоком переключателя, может нормально завершиться, если он достижим.

     

Непустой блок, который не является блоком переключателя, может завершиться нормально, если последний оператор в нем может завершиться нормально.

     

Первая инструкция в непустом блоке, который не является блоком переключателя, достижима, если блок достижим.

     

Любой другой оператор S в непустом блоке, который не является блоком переключателя, достижим, если оператор, предшествующий S, может завершиться нормально.

Метод letsThrow соответствует критериям для рабочего блока кода и технически обычно завершается . Выдает исключение, но завершает. Независимо от того, генерирует ли оно гарантированное исключение, при определении того, действительно ли этот блок кода используется в действительности, не учитывается, только то, может ли оно быть достигнуто . В большинстве случаев мертвый код будет обнаружен только в том случае, если он использует try /catch /return, что составляет основную часть правил.

Рассмотрим следующую, еще более краткую версию:

@Test 
public void testDeadCode() {
    System.exit(0);
    System.out.println("will never be reached");
}

Реального счетчика для этого нет, кроме усердного использования инструментов покрытия, но яркой стороной в вашем примере является то, что вы будете видеть гарантированные исключения при каждом запуске кода.

ответил Compass 8 J0000006Europe/Moscow 2016, 18:00:02
0

Постарайтесь пройти комплексные юнит-тесты и измерить охват тестами. Мертвый код будет заметен, потому что ни один из ваших тестов не приводит к его выполнению.

ответил Raedwald 8 J0000006Europe/Moscow 2016, 17:44:54
0

Объявите ваш метод как возвращающий бросаемый тип:

private final RuntimeException letsThrow() {
  throw new RuntimeException("guess you didnt see this one coming");
}

Тогда вы можете бросить, когда вы называете это:

throw letsThrow();

Теперь любой код, следующий за вызовом letsThrow(), будет обнаружен как мертвый.

Вы можете применить это, проверив случаи, когда возвращаемое значение letsThrow() не используется с помощью инструмента статического анализа. Например, errorprone Google имеет средство проверки для @CheckReturnValue аннотация , которая гарантирует, что вы используете результат.

(Для версии бедного человека найдите регулярное выражение ^\s*letsThrow();).

ответил Andy Turner 8 J0000006Europe/Moscow 2016, 18:00:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132