unreachable traduction statement significa que java language-design unreachable-statement

traduction - ¿Por qué Java tiene un error de compilador de "declaración inalcanzable"?



unreachable statement java que significa (8)

Es Nanny. Siento que .Net acertó: muestra una advertencia de código inalcanzable, pero no un error. Es bueno ser advertido al respecto, pero no veo ninguna razón para evitar la compilación (especialmente durante las sesiones de depuración en las que es bueno lanzar una devolución para eludir algún código).

A menudo encuentro que al depurar un programa es conveniente (aunque podría decirse que una mala práctica) insertar una declaración de devolución dentro de un bloque de código. Podría intentar algo como esto en Java ...

class Test { public static void main(String args[]) { System.out.println("hello world"); return; System.out.println("i think this line might cause a problem"); } }

por supuesto, esto produciría el error del compilador.

Test.java:7: declaración inalcanzable

Pude entender por qué una advertencia podría justificarse porque tener un código sin usar es una mala práctica. Pero no entiendo por qué esto necesita generar un error.

¿Es solo Java tratando de ser una niñera, o hay una buena razón para hacer de esto un error de compilación?


No hay una razón definitiva por la cual las declaraciones inalcanzables no deben permitirse; otros idiomas los permiten sin problemas. Para su necesidad específica, este es el truco habitual:

if (true) return;

Parece absurdo, cualquiera que lea el código adivinará que debe haberlo hecho deliberadamente, no un error descuidado de dejar el resto de las declaraciones inalcanzables.

Java tiene un poco de soporte para la "compilación condicional"

http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.21

if (false) { x=3; }

no da como resultado un error en tiempo de compilación. Un compilador de optimización puede darse cuenta de que la declaración x = 3; nunca se ejecutará y puede optar por omitir el código para esa declaración del archivo de clase generado, pero la instrucción x = 3; no se considera "inalcanzable" en el sentido técnico especificado aquí.

La razón de este tratamiento diferente es permitirles a los programadores definir "variables de bandera" tales como:

static final boolean DEBUG = false;

y luego escribe un código como:

if (DEBUG) { x=3; }

La idea es que sea posible cambiar el valor de DEPURAR de falso a verdadero o de verdadero a falso y luego compilar el código correctamente sin ningún otro cambio en el texto del programa.


Porque el código inalcanzable no tiene sentido para el compilador. Si bien hacer código significativo para las personas es primordial y más difícil que hacerlo significativo para un compilador, el compilador es el consumidor esencial de código. Los diseñadores de Java toman el punto de vista de que el código que no es significativo para el compilador es un error. Su postura es que si tiene algún código inalcanzable, ha cometido un error que debe corregirse.

Aquí hay una pregunta similar: Código inalcanzable: ¿error o advertencia? , en el que el autor dice "Personalmente, creo firmemente que debería ser un error: si el programador escribe un código, siempre debe ser con la intención de ejecutarlo en algún escenario". Obviamente, los diseñadores de lenguaje de Java están de acuerdo.

Si el código inalcanzable debe evitar la compilación es una pregunta sobre la cual nunca habrá consenso. Pero esta es la razón por la cual los diseñadores de Java lo hicieron.

Varias personas en comentarios señalan que hay muchas clases de código inalcanzable. Java no impide la compilación. Si entiendo las consecuencias de Gödel correctamente, ningún compilador puede atrapar todas las clases de código inalcanzable.

Las pruebas unitarias no pueden detectar todos los errores. No usamos esto como argumento en contra de su valor. Del mismo modo, un compilador no puede detectar todos los códigos problemáticos, pero sigue siendo valioso para evitar la compilación de código incorrecto cuando puede.

Los diseñadores de lenguaje Java consideran que el código inalcanzable es un error. Por lo tanto, es razonable evitar la compilación cuando sea posible.

(Antes de votar: la pregunta no es si Java debe tener un error de compilador de sentencia inalcanzable. La pregunta es por qué Java tiene un error de compilador de sentencia inalcanzable. No me rechaces solo porque piensas que Java tomó una decisión de diseño equivocada).


Si bien creo que este error de compilación es bueno, hay una manera de evitarlo. Use una condición que sepa que será verdadera:

public void myMethod(){ someCodeHere(); if(1 < 2) return; // compiler isn''t smart enough to complain about this moreCodeHere(); }

El compilador no es lo suficientemente inteligente como para quejarse de eso.


Si el motivo para permitir el if (aBooleanVariable) return; someMoreCode; if (aBooleanVariable) return; someMoreCode; es permitir banderas, luego el hecho de que if (true) return; someMoreCode; if (true) return; someMoreCode; no genera un error de tiempo de compilación parece una inconsistencia en la política de generación de excepción CodeNotReachable, ya que el compilador ''sabe'' que true no es un indicador (no una variable).

Otras dos formas que pueden ser interesantes, pero no se aplican a la desactivación de parte del código de un método, así como a la if (true) return :

Ahora, en lugar de decir if (true) return; es posible que desee decir " assert false y agregar -ea OR -ea package OR -ea className a los argumentos de jvm. Lo bueno es que esto permite cierta granularidad y requiere agregar un parámetro extra a la invocación de jvm, por lo que no es necesario establecer un indicador DEBUG en el código, sino mediante un argumento adicional en tiempo de ejecución, que es útil cuando el objetivo no es el la máquina del desarrollador y la recompilación y transferencia del bytecode lleva tiempo.

También existe el modo System.exit(0) , pero esto podría ser una exageración, si lo coloca en Java en un JSP terminará el servidor.

Además de que Java es un lenguaje de ''niñera'', prefiero usar algo nativo como C / C ++ para tener más control.


Sin duda es bueno quejarse, cuanto más estricto sea el compilador, mejor será, siempre que le permita hacer lo que necesita. Por lo general, el pequeño precio a pagar es comentar el código, la ganancia es que cuando compilas tu código funciona. Un ejemplo general es Haskell acerca de qué personas gritan hasta que se dan cuenta de que su prueba / depuración es solo la prueba principal y la corta. Personalmente, en Java casi no hago ninguna depuración estando (de hecho a propósito) no atento.


Solo me di cuenta de esta pregunta y quería agregar mi $ .02 a esto.

En el caso de Java, esto no es realmente una opción. El error de "código inalcanzable" no proviene del hecho de que los desarrolladores de JVM pensaban proteger a los desarrolladores de nada, o ser más vigilantes, sino de los requisitos de la especificación de JVM.

Tanto el compilador de Java como JVM usan lo que se llama "mapas de pila": una información definitiva sobre todos los elementos de la pila, tal como se asignaron para el método actual. Se debe conocer el tipo de cada ranura de la pila, de modo que una instrucción JVM no maltrate elementos de un tipo para otro tipo. Esto es más importante para evitar que se utilice un valor numérico como puntero. Es posible, mediante el ensamblaje de Java, intentar insertar / almacenar un número, pero luego mostrar / cargar una referencia de objeto. Sin embargo, JVM rechazará este código durante la validación de la clase, es decir, cuando los mapas de pila se creen y se prueben por coherencia.

Para verificar los mapas de pila, la máquina virtual debe recorrer todas las rutas de código existentes en un método y asegurarse de que, independientemente de la ruta de código que se ejecute alguna vez, los datos de la pila para cada instrucción coinciden con lo que haya introducido cualquier código anterior. / almacenado en la pila. Entonces, en caso simple de:

Object a; if (something) { a = new Object(); } else { a = new String(); } System.out.println(a);

en la línea 3, JVM comprobará que ambas ramas de ''si'' solo han almacenado en un (que es simplemente var local 0) algo que es compatible con Object (ya que así es como el código de la línea 3 y on tratará var local 0 )

Cuando el compilador llega a un código inalcanzable, no sabe muy bien en qué estado se encuentra la pila en ese punto, por lo que no puede verificar su estado. Ya no puede compilar el código en ese punto, ya que tampoco puede hacer un seguimiento de las variables locales, por lo que en lugar de dejar esta ambigüedad en el archivo de clase, produce un error fatal.

Por supuesto, una condición simple como if (1<2) engañará, pero no es realmente engañoso: le está dando una rama potencial que puede conducir al código, y al menos tanto el compilador como la VM pueden determinar cómo la pila los artículos se pueden usar desde allí en adelante.

PD: No sé qué hace .NET en este caso, pero creo que también fallará la compilación. Esto normalmente no será un problema para ningún compilador de códigos de máquina (C, C ++, Obj-C, etc.)


Uno de los objetivos de los compiladores es descartar clases de errores. Algún código inalcanzable está allí por accidente, es bueno que javac descarte esa clase de error en tiempo de compilación.

Por cada regla que capte código erróneo, alguien querrá que el compilador lo acepte porque sabe lo que está haciendo. Esa es la pena de la verificación del compilador, y obtener el equilibrio correcto es uno de los puntos clave del diseño del lenguaje. Incluso con el control más estricto todavía hay una cantidad infinita de programas que se pueden escribir, por lo que las cosas no pueden ser tan malas.