Я только что заметил этот вопрос и хотел добавить к нему $ .02.
В случае Java это на самом деле не вариант. Ошибка «недостижимого кода» исходит не из того, что разработчики JVM думали защищать разработчиков от чего-либо или быть более бдительными, но из требований спецификации JVM.
Как Java-компилятор, так и JVM используют так называемые «карты стека» - определенную информацию обо всех элементах в стеке, выделенных для текущего метода. Тип каждого слота стека должен быть известен, так что команда JVM не будет беспокоить элемент одного типа для другого типа. Это в основном важно для предотвращения использования числового значения в качестве указателя. Возможно, используя сборку Java, попытаться нажать/сохранить номер, но затем поп/загрузить ссылку на объект. Однако JVM будет отклонять этот код во время проверки класса, то есть когда создаются карты стека и проверяются на согласованность.
Чтобы проверить карты стека, виртуальная машина должна пройти все пути кода, существующие в методе, и убедиться, что независимо от того, какой путь кода будет выполняться, данные стека для каждой команды согласуются с тем, что предыдущий код был нажат/сохранен в стеке. Так, в простом случае:
Object a;
if (something) { a = new Object(); } else { a = new String(); }
System.out.println(a);
в строке 3, JVM проверит, что обе ветви «если» только хранится в (это просто локальная переменная # 0) то, что совместимо с объектом (с вот как код из строки 3 и далее будет обрабатывать локальный var # 0).
Когда компилятор добирается до недостижимого кода, он не совсем знает, в каком состоянии может находиться стек в этой точке, поэтому он не может проверить его состояние. В этом случае он больше не может компилировать код, так как он также не может отслеживать локальные переменные, поэтому вместо того, чтобы оставлять эту двусмысленность в файле класса, возникает фатальная ошибка.
Конечно, простое условие, такое как if (1<2)
, обманет его, но это действительно не обманывает - это дает ему потенциальную ветвь, которая может привести к коду, и по крайней мере как компилятор, так и виртуальная машина могут определить, как элементы стека можно использовать оттуда.
P.S. Я не знаю, что делает .NET в этом случае, но я считаю, что это тоже не скомпилит. Это обычно не будет проблемой для компиляторов машинного кода (C, C++, Obj-C и т. Д.)
Java тоже не совсем последовательна. Для некоторых потоков управления, которые вызывают мертвый код, но Java не жалуется. Для других это так. Определение того, что код мертв является невычислимой проблемой. Я не знаю, почему Java решила начать что-то, чего он не смог закончить. –