2012-05-08 14 views
9

Según mi experimentación científica Java, int x = 0; es equivalente a int x = 0;; lo que equivale a int x = 0;;;;;;;;;;;;;;;¿Por qué compila el código con dos puntos y comas sucesivos?

  1. ¿Por qué Java permite esto? ¿Tiene alguna aplicación práctica?
  2. ¿Son estas declaraciones solo vacías? ¿De hecho toman algún tiempo de procesamiento extra durante el tiempo de ejecución? (¿Asumiría que están optimizados?)
  3. ¿Hacen otros idiomas esto? Supongo que es algo heredado de C, como muchas cosas en Java. ¿Es esto cierto?
+0

No puedo pensar en un lenguaje que no permita declaraciones vacías (siempre que sea posible escribirlas en primer lugar) – trutheality

+0

@trutheality, Ada no permite declaraciones vacías. Para indicar explícitamente una declaración vacía, escriba 'null'. Consulte http://archive.adaic.com/standards/83rat/html/ratl-03-07.html para ver un ejemplo. –

Respuesta

18

Como Jake King escribe, puede producir declaraciones vacías que hacer nada en un bucle:

while (condition); 

pero para que sea obvio, podría escribir

while (condition) 
    ; 

o incluso mejor:

while (condition) 
/** intentionally empty */ 
    ; 

o mejor aún, como Michael Kjörling señaló en el comentario,

while (condition) 
{ 
    /** intentionally empty */ 
} 

Más a menudo, se ven en para-declaraciones de bucles sin fin:

for (;;) 

o sólo una instrucción vacía

for (start;;) 
for (;cond;) 
for (;;end) 

Otra cosa que puede hacer, es decir, a escribir una programa, una vez con uno, y una vez con 2 punto y coma:

public class Empty 
{ 
    public static void main (String args[]) 
    { 
     System.out.println ("Just semicolons");; 
    } 
} 

Compile y ejecute list el tamaño del código byte (idéntico) y haga un md5sum en bytecode (identic).

Por lo tanto, en los casos en que la semántica no se modifica, se optimiza claramente, al menos para el compilador de 1.6 Oracle puedo decirlo.

+0

C puede incluso hacer 'while (condition);' que también se ejecuta como una instrucción. – aitchnyu

+0

En los casos muy raros que uno necesita un bloque de instrucción de ciclo while vacío, me parece mejor escribirlo como una encarnación de 'while (condición) {}' en lugar de 'while (condición);' (un comentario arrojado es otra buena manera de hacerlo). El punto y coma se puede pasar por alto fácilmente, pero las llaves son explícitas. ** También **, aunque no diré que no use una función de idioma porque alguien podría no saberlo, un terminador de declaración aparentemente erróneo es una barrera mental, que a menudo es mejor evitar para facilitar la comprensión del código. –

21

Los puntos y comas adicionales se tratan como declaraciones vacías. Las declaraciones vacías no hacen nada, por eso Java no se queja de eso.

8

Sí, son declaraciones vacías, que no hacen nada en absoluto. Están optimizados por el compilador, pero en algunos casos esta declaración vacía realmente hace algo, haciendo lo mismo que un conjunto de llaves vacías ({}). Se heredan de la sintaxis C, pero tienen pocos usos en Java. En C, a veces haciendo algo como esto era útil:

while (condition); 

Este bucle hasta condition es falso, la prevención de código de progresar. Sin embargo, esto se desaconseja en el código moderno, y nunca debería usarse realmente en Java. Sin embargo, la declaración vacía hace recuento como una declaración, sólo un inútil, por lo que las construcciones de este tipo:

if (condition); 
    doSomething(); 

.... pueden causar resultados un tanto desconcertante. La instrucción if llamará a la instrucción vacía, no al método, por lo que se llamará al método siempre. Solo una advertencia para tener en cuenta.

+0

+1, pero estoy bastante seguro de que el compilador optimiza (elimina) las declaraciones vacías. – Jeremy

+0

@Jeremy No es así, las declaraciones vacías se dejan porque hacen, de hecho, algo. Técnicamente cuentan como declaraciones, simplemente no hacen nada. Eso es diferente de la eliminación completa de las declaraciones en sí mismas. –

+3

Al compilar [estas dos clases] (https://www.refheap.com/paste/2645) se genera exactamente el mismo código de bytes (con la excepción del nombre de la clase). El punto y coma al final de 'while (true);' no es una declaración vacía. Termina el ciclo while sin un bloque. – Jeremy

0

Una cosa a tener en cuenta es que si haces algo como esto:

public int foo() 
{ 
    return(0);; 
} 

el compilador/puede quejarse de un estado inalcanzable porque hay una sentencia vacía después de un retorno. Al menos con 1.6 sdk de Oracle lo hace.

Cuestiones relacionadas