Dopiero co zauważyłem to pytanie i chciałem dodać do niego 0,02 $.
W przypadku Javy nie ma takiej możliwości. Błąd „nieosiągalnego kodu” nie wynika z faktu, że programiści JVM myśleli, że powinni chronić programistów przed czymkolwiek lub zachować szczególną czujność, ale z wymagań specyfikacji JVM.
Zarówno kompilator Java, jak i JVM używają tak zwanych „map stosu” - określonej informacji o wszystkich elementach stosu, przydzielonych dla bieżącej metody. Typ każdej szczeliny stosu musi być znany, aby instrukcja JVM nie traktowała elementu jednego typu dla innego typu. Jest to szczególnie ważne, aby zapobiec używaniu wartości liczbowej jako wskaźnika. Jest możliwe, używając zestawu Java, aby spróbować wypchnąć / zapisać liczbę, a następnie pobrać / załadować odwołanie do obiektu. Jednak JVM odrzuci ten kod podczas sprawdzania poprawności klas, czyli wtedy, gdy mapy stosu są tworzone i testowane pod kątem spójności.
Aby zweryfikować mapy stosu, maszyna wirtualna musi przejść przez wszystkie ścieżki kodu istniejące w metodzie i upewnić się, że bez względu na to, która ścieżka kodu zostanie kiedykolwiek wykonana, dane stosu dla każdej instrukcji są zgodne z tym, co przekazał poprzedni kod / przechowywane w stosie. A więc w prostym przypadku:
Object a;
if (something) { a = new Object(); } else { a = new String(); }
System.out.println(a);
w linii 3, JVM sprawdzi, czy obie gałęzie 'if' zapisały tylko w (która jest po prostu lokalną zmienną # 0) czymś, co jest kompatybilne z Object (ponieważ tak kod z linii 3 i następnych będzie traktował lokalną zmienną # 0 ).
Kiedy kompilator dociera do nieosiągalnego kodu, nie do końca wie, w jakim stanie może być stos w tym momencie, więc nie może zweryfikować jego stanu. W tym momencie nie może już skompilować kodu, ponieważ nie może również śledzić zmiennych lokalnych, więc zamiast pozostawić tę niejednoznaczność w pliku klasy, generuje błąd krytyczny.
Oczywiście prosty warunek, taki jak if (1<2)
, oszuka go, ale tak naprawdę nie jest to głupi - daje mu potencjalną gałąź, która może prowadzić do kodu, a przynajmniej zarówno kompilator, jak i maszyna wirtualna mogą określić, w jaki sposób elementy stosu mogą być stamtąd używane na.
PS Nie wiem, co robi .NET w tym przypadku, ale sądzę, że kompilacja również się nie powiedzie. Zwykle nie będzie to problemem dla żadnych kompilatorów kodu maszynowego (C, C ++, Obj-C itp.)