2012-06-11 44 views
9

Java cho phép các từ khóa nhất định được theo sau bởi một câu lệnh hoặc một khối câu lệnh. Ví dụ:Tại sao thử/bắt hoặc đồng bộ trong Java yêu cầu một khối lệnh?

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

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

biên dịch cũng như như

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

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

này cũng đúng đối với các từ khóa như for, while, vv

Tuy nhiên, một số từ khóa không cho phép điều này. synchronized yêu cầu một câu lệnh chặn. Tương tự cho try ... catch ... finally, yêu cầu ít nhất hai câu lệnh chặn theo từ khóa. Ví dụ:

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

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

công trình, nhưng sau đây không biên dịch:

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

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

Vậy tại sao một số từ khóa trong Java đòi hỏi một tuyên bố khối, trong khi số khác cho phép một tuyên bố khối cũng như một đĩa đơn tuyên bố? Đây có phải là sự không nhất quán trong thiết kế ngôn ngữ hay không, hoặc có lý do nào đó cho điều này?

+5

tôi nghi ngờ cách tiếp cận câu lệnh đơn được cau mày và chỉ được sử dụng vì có thể có điều tương tự trong c. vì c không được đồng bộ hóa hoặc cố gắng chúng có thể đi kèm với tùy chọn "an toàn hơn". –

+1

Vì đó là cú pháp; AFAIK không có lý do kỹ thuật phải có một khối, vì nó có thể được tạo tự động. –

+0

Đây là dự đoán của tôi, FWIW: Các nhà thiết kế ngôn ngữ muốn giữ một cú pháp đủ tương tự với các ngôn ngữ khác để hỗ trợ việc học. Nhưng cảm thấy nơi các tính năng ngôn ngữ mới được thêm vào, họ sẽ thực thi những gì một số cảm thấy là một tiêu chuẩn mã hóa tốt hơn. Hoặc, có lẽ, đối với các tính năng ngôn ngữ ít được sử dụng thường xuyên hơn, họ đã cho ý tưởng của họ về mã hóa tốt hơn? – Marvo

Trả lời

4

Bạn nhận được một sự mơ hồ giống như mơ hồ khác nếu bạn cố gắng cho phép rời khỏi niềng răng. Trong khi điều này có thể được giải quyết trong một thời trang tương tự như các lủng lẳng khác, có lẽ tốt nhất không.

Cân nhắc

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

Điều đó có nghĩa

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

hoặc

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

Tôi tin vào CLU, khối catch là xung quanh chỉ là một tuyên bố (có thể sai).

+1

Câu trả lời hay. +1 – EJP

+0

Bạn có vấn đề tương tự với if/else blocks. Tôi nghĩ rằng đó là một vấn đề chung mà các nhà thiết kế muốn tránh những vấn đề này. –

+0

Cảm ơn ví dụ điển hình, Tom. Tuy nhiên, điều này không giải thích được câu hỏi của tôi về biểu thức được đồng bộ hóa. – Bob

2

Đó chỉ là quyết định thiết kế của ngôn ngữ và cơ chế biên dịch của nó.

Tôi đồng ý với quyết định. Không yêu cầu một khối mã có thể làm cho mã ngắn hơn, nhưng đó là một cách chắc chắn cháy để gây nhầm lẫn và tạo ra những hậu quả không lường trước được.

+0

Tôi đã đề cập đến thiết kế của trình biên dịch, không phải nếu nó có thể làm việc mà không có nó. Trình biên dịch Java không chấp nhận nó. Có lẽ một từ ngữ tốt hơn sẽ là "quyết định thiết kế trình biên dịch". –

+0

Sở hữu. Đã sửa. –

+0

@ Jonathan: Ah, được rồi. :-) –

1

Có vấn đề với việc không sử dụng {} ngay cả với câu lệnh cho phép điều này có thể gây nhầm lẫn. Cách đối phó với điều này là sử dụng mã định dạng một cách chặt chẽ. Nhiều nơi yêu cầu {} luôn tránh các vấn đề.

ví dụ:

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 

Tôi tin rằng lý do bạn có thể làm điều này cho một số báo cáo và không phải người khác từ từ C. Trong C bạn có thể sử dụng nếu/làm/khi/cho mà không có một khối tuyên bố. Tuy nhiên, thử/bắt và đồng bộ đã được thêm vào trong Java. Có hai lý do tại sao chúng chỉ có {} khối.

  • nó được coi là tốt nhất
  • nó là đơn giản để cho phép chỉ có một lựa chọn.

Với Java là ngôn ngữ tính năng gọn gàng, tôi nghi ngờ nó là sau này nhiều hoặc nhiều hơn trước đây.