2012-06-11 12 views
9

Java consente a determinate parole chiave di essere seguite da un'istruzione o da un blocco di istruzioni. Per esempio:Perché try/catch o synchronized in Java richiede un blocco di istruzioni?

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

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

compila così come

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

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

Questo vale anche per le parole chiave come for, while ecc

Tuttavia, alcune parole chiave non consentono questo. synchronized richiede una dichiarazione di blocco. Lo stesso per try ... catch ... finally, che richiede almeno due istruzioni di blocco che seguono le parole chiave. Per esempio:

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

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

opere, ma il seguente non compila:

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

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

Allora perché alcune parole chiave in Java richiedono una dichiarazione di blocco, mentre altri permettono una dichiarazione di blocco così come un unico affermazione? Si tratta di un'incoerenza nella progettazione della lingua, o c'è una ragione per questa?

+5

ho il sospetto che l'approccio di una singola dichiarazione sia disapprovato e utilizzato solo perché qualcosa di simile è possibile in c. dato che c non ha sincronizzato o provato, probabilmente è andato con l'opzione "più sicura". –

+1

Perché questa è la sintassi; AFAIK non ci sono motivi tecnici per cui ci deve essere un blocco, poiché potrebbe essere creato automaticamente. –

+0

Ecco la mia ipotesi, FWIW: I progettisti linguistici volevano mantenere una sintassi abbastanza simile ad altre lingue per facilitare l'apprendimento. Ma sentivo dove venivano aggiunte nuove funzionalità linguistiche, avrebbero rinforzato quello che secondo alcuni è uno standard di codifica migliore. O forse, per le funzionalità linguistiche meno frequentemente utilizzate, è stata presa l'idea di una migliore codifica? – Marvo

risposta

4

Se si tenta di lasciare fuori le parentesi graffe, si ottiene un'ambiguità tutt'altro che banale. Mentre questo potrebbe essere risolto in modo simile al penzoloni, altrimenti è meglio non farlo.

consideri

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

Vuol dire che

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(); 

Credo in CLU, blocchi catch erano intorno a una sola istruzione (potrebbe essere sbagliato).

+1

Buona risposta. +1 – EJP

+0

Hai un problema simile con if/else blocks. Penso che dato il suo problema comune i progettisti vogliono evitare questi problemi. –

+0

Grazie per il buon esempio, Tom. Tuttavia, questo non spiega la mia domanda riguardo all'espressione sincronizzata. – Bob

2

È solo la decisione di progettazione del linguaggio e la sua meccanica del compilatore.

Sono d'accordo con la decisione. Non richiedere un blocco di codice potrebbe rendere il codice più breve, ma è un modo sicuro per creare confusione e creare conseguenze impreviste.

+0

Mi riferivo al design del compilatore, non se potesse funzionare senza di esso. Il compilatore Java non lo accetta. Forse una formulazione migliore sarebbe stata "decisione di progettazione del compilatore". –

+0

Possente. Fisso. –

+0

@ Jonathan: Ah, ok. :-) –

1

Ci sono problemi con il non utilizzo di {} anche con le istruzioni che consentono questo può essere confusione. Il modo in cui un accordo con questo è di usare rigorosamente i formattatori di codice. Molti posti richiedono {} sempre per evitare problemi.

ad es.

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 

Credo che la ragione si può fare questo per alcune affermazioni e non altri da da C. In C si può utilizzare se/fare/mentre/per senza un blocco di istruzioni. Comunque try/catch e synchronized sono stati aggiunti in Java. Ci sono due ragioni per cui questi hanno solo {} blocchi.

  • si è ritenuto migliori pratiche
  • è più semplice per consentire una sola opzione.

Dato che Java è un linguaggio di funzionalità, sospetto che sia il più tardi o più del primo.

Problemi correlati