2012-05-08 26 views
9

Theo thử nghiệm Java khoa học của tôi, int x = 0; tương đương với int x = 0;; tương đương với int x = 0;;;;;;;;;;;;;;;Tại sao mã với các dấu chấm phẩy liên tiếp biên dịch?

  1. Tại sao Java cho phép điều này? Nó có ứng dụng thực tế nào không?
  2. Mỗi câu trong số này chỉ là các câu lệnh trống? Họ có thực sự mất thêm thời gian xử lý nào trong thời gian chạy không? (Tôi cho rằng chúng chỉ được tối ưu hóa?)
  3. Các ngôn ngữ khác có làm được điều này không? Tôi đoán đó là một cái gì đó được thừa kế từ C, giống như rất nhiều thứ trong Java. Điều này có đúng không?
+0

Tôi không thể nghĩ ra ngôn ngữ không cho phép báo cáo trống (miễn là có thể viết chúng ở nơi đầu tiên.) – trutheality

+0

@trutheality, Ada không cho phép báo cáo trống. Để chỉ rõ một câu lệnh trống, bạn viết ‘null’. Xem http://archive.adaic.com/standards/83rat/html/ratl-03-07.html để biết ví dụ. –

Trả lời

18

Như Jake vua viết, bạn có thể tạo báo cáo có sản phẩm nào để làm gì trong một vòng lặp:

while (condition); 

nhưng để làm cho nó rõ ràng, bạn sẽ viết

while (condition) 
    ; 

hoặc thậm chí tốt hơn:

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

hoặc thậm chí tốt hơn, như Michael Kjörling đã chỉ ra trong nhận xét,

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

Thông thường, bạn sẽ thấy nó trong cho-báo cáo cho vòng lặp vô tận:

for (;;) 

hoặc chỉ có một sản phẩm nào tuyên bố

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

Một điều bạn có thể làm, là, để viết một chương trình, một lần với một và một lần với 2 dấu chấm phẩy:

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

Biên dịch nó, và chạy danh sách kích thước của mã byte (identic) và làm một md5sum trên bytecode (identic).

Vì vậy, trong trường hợp, khi ngữ nghĩa không thay đổi, nó được tối ưu hóa rõ ràng, ít nhất là đối với trình biên dịch 1.6-Oracle, tôi có thể nói như vậy.

+0

C thậm chí có thể thực hiện 'while (condition);' cũng được thực thi như một câu lệnh. – aitchnyu

+0

Trong những trường hợp rất hiếm hoi mà người ta cần một khối lệnh trống trong vòng lặp, tôi thấy nó tốt hơn để viết nó như là một số hóa thân của 'while (condition) {}' thay vì 'while (condition);' (một chú thích được ném vào là một cách tốt để làm điều đó). Dấu chấm phẩy có thể dễ dàng bị bỏ qua, nhưng niềng răng là rõ ràng. ** Ngoài ra **, trong khi tôi sẽ không nói không sử dụng tính năng ngôn ngữ bởi vì ai đó có thể không biết nó, một người kết thúc câu lệnh có vẻ khó hiểu là một rào cản tinh thần, thường được tránh tốt nhất để tạo điều kiện hiểu mã. –

21

Dấu chấm phẩy bổ sung được coi là báo cáo trống. Các câu lệnh trống không làm gì cả, vì vậy đó là lý do tại sao Java không phàn nàn về nó.

8

Có, chúng là các câu lệnh trống, không làm gì cả. Chúng được tối ưu hóa bởi trình biên dịch, nhưng trong một số trường hợp, câu lệnh trống này thực sự làm điều gì đó, làm điều tương tự như một tập các dấu ngoặc rỗng ({}). Chúng được kế thừa từ cú pháp C, nhưng chúng có ít sử dụng trong Java. Trong C, đôi khi làm điều gì đó như thế này hữu ích:

while (condition); 

Điều này sẽ lặp lại cho đến khi condition là sai, ngăn không cho mã tiến triển. Tuy nhiên, điều này không được khuyến khích trong mã hiện đại và không bao giờ thực sự được sử dụng trong Java. Tuy nhiên, tuyên bố rỗng không đếm như một tuyên bố, chỉ cần một cái vô dụng, vì vậy cấu trúc như thế này:

if (condition); 
    doSomething(); 

.... có thể gây ra kết quả hơi khó hiểu. Tuyên bố if sẽ gọi câu lệnh trống, không phải phương thức, vì vậy phương pháp sẽ luôn gọi. Chỉ cần báo trước để ghi nhớ.

+0

+1, nhưng tôi khá chắc chắn trình biên dịch tối ưu hóa (loại bỏ) các câu lệnh trống. – Jeremy

+0

@ Jeremy Không phải như vậy, các câu nói trống còn lại trong khi họ làm, trên thực tế, làm điều gì đó. Về mặt kỹ thuật, chúng được tính là báo cáo, chúng không làm gì cả. Điều đó khác với việc loại bỏ hoàn toàn các câu lệnh. –

+3

Biên dịch [hai lớp này] (https://www.refheap.com/paste/2645) tạo chính xác bytecode (ngoại trừ tên lớp). Dấu chấm phẩy ở cuối 'while (true);' không phải là một câu lệnh trống. Nó kết thúc vòng lặp while với một khối. – Jeremy

0

Một điều cần lưu ý là nếu bạn làm điều gì đó như thế này:

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

Trình biên dịch sẽ/có thể phàn nàn về một tuyên bố không thể truy cập bởi vì có một tuyên bố trống sau khi quay trở lại. Ít nhất với 1,6 sdk của Oracle nó.

Các vấn đề liên quan