2012-06-11 10 views
9

Java permite que ciertas palabras clave sean seguidas por una instrucción o un bloque de instrucciones. Por ejemplo:¿Por qué try/catch o synchronized en Java requiere un bloque de instrucciones?

if (true) 
    System.out.println("true"); 

do 
    System.out.println("true"); 
while (true); 

compila, así como

if(true) { 
    System.out.println("true"); 
} 

do { 
    System.out.println("true"); 
} while (true); 

Esto también es cierto para las palabras claves como for, etc. while

Sin embargo, algunas palabras clave no permiten esto. synchronized requiere una instrucción de bloque. Lo mismo para try ... catch ... finally, que requiere al menos dos instrucciones de bloque después de las palabras clave. Por ejemplo:

try { 
    System.out.println("try"); 
} finally { 
    System.out.println("finally"); 
} 

synchronized(this) { 
    System.out.println("synchronized"); 
} 

obras, pero el siguiente no se compila:

try 
    System.out.println("try"); 
finally 
    System.out.println("finally"); 

synchronized (this) 
    System.out.println("synchronized"); 

Entonces, ¿por qué algunas palabras clave en Java requieren una declaración de bloque, mientras que otros permiten una sentencia de bloque, así como una sola ¿declaración? ¿Es esto una incoherencia en el diseño del lenguaje, o hay alguna razón para esto?

+5

sospecho que el enfoque de declaración única está mal visto y se usa solo porque algo similar es posible en c. dado que c no se ha sincronizado o intentado, probablemente fueron con la opción "más segura". –

+1

Porque esa es la sintaxis; AFAIK no hay ningún motivo técnico por el que deba haber un bloqueo, ya que podría crearse automáticamente. –

+0

Aquí está mi suposición, FWIW: Los diseñadores de idiomas querían mantener una sintaxis similar a otros idiomas para ayudar en el aprendizaje. Pero sintieron que cuando se agregaron nuevas características del lenguaje, harían cumplir lo que algunos sienten que es un mejor estándar de codificación. O, tal vez, para las características de lenguaje menos utilizadas, ¿aceptaron su idea de una mejor codificación? – Marvo

Respuesta

4

Obtendrá una ambigüedad de otro tipo si intenta dejar de lado los refuerzos. Si bien esto podría resolverse de una manera similar a la del resto, probablemente sea mejor no hacerlo.

Considere

try 
try 
fn(); 
catch (GException exc) 
g(); 
catch (HException exc) 
h(); 
catch (IException exc) 
i(); 

¿Eso significa que

try 
    try 
     fn(); 
    catch (GException exc) 
     g(); 
    catch (HException exc) 
     h(); 
catch (IException exc) 
    i(); 

o

try 
    try 
     fn(); 
    catch (GException exc) 
     g(); 
catch (HException exc) 
    h(); 
catch (IException exc) 
    i(); 

Creo en CLU, bloques catch eran alrededor de sólo una declaración (que puede estar mal).

+1

Buena respuesta. +1 – EJP

+0

Tiene un problema similar con los bloques if/else. Creo que dado que es un problema común, los diseñadores quieren evitar estos problemas. –

+0

Gracias por el buen ejemplo, Tom. Sin embargo, esto no explica mi pregunta con respecto a la expresión sincronizada. – Bob

2

Es solo la decisión de diseño del lenguaje y su mecánica de compilación.

Estoy de acuerdo con la decisión. No requerir un bloque de código puede hacer que el código sea más corto, pero es una manera segura de causar confusión y crear consecuencias imprevistas.

+0

Me refería al diseño del compilador, no si podría funcionar sin él. El compilador de Java simplemente no lo acepta. Tal vez una mejor redacción habría sido "decisión de diseño del compilador". –

+0

Posesivo. Fijo. –

+0

@ Jonathan: Ah, está bien. :-) –

1

Existen problemas al no usar {} incluso con declaraciones que permiten que haya confusión. La forma de tratar esto es utilizar rigurosamente los formateadores de código. Muchos lugares requieren {} siempre para evitar problemas.

p. Ej.

if (condition) 
    if (condition2) 
     statement 
    else // which if 
    statement 

do 
    statement 
    while (condition) // is it do/while or an inner loop? 
     statement 
    while (condition2) 
    statement 

Creo que la razón puede hacer esto por algunas declaraciones y no otros de a partir de C. En C se puede usar si/do/while/porque sin un bloque de instrucciones. Sin embargo try/catch y synchronized se han agregado en Java. Hay dos razones por las que solo tienen {} bloques.

  • se consideró la mejor práctica
  • es más simple para permitir sólo una opción.

Dado que Java es un lenguaje de características lean, sospecho que es el último tanto o más que el primero.

Cuestiones relacionadas