2012-02-09 30 views
57

Tại sao điều này đầu tiên if biên dịch tốt và lỗi thứ hai không thành công?Lỗi trình biên dịch khi khai báo một biến bên trong nếu điều kiện và không có dấu ngoặc nhọn

if(proceed) {int i;} // This compiles fine. 
if(proceed) int i;// This gives an error. (Syntax error on token ")", { expected after this token) 
+2

liên quan này: tuyên bố [Object tạo trong Java không cho phép sử dụng vòng lặp một đường. Tại sao?] (Http://stackoverflow.com/questions/8145663/object-creating-statement-in-java-doesnt-allow-to-use-a-single-line-loop-why) – Lion

Trả lời

72

Bởi vì spec ngôn ngữ nói như vậy:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html

Một tuyên bố giới thiệu một thực thể vào một chương trình và bao gồm một định danh (§3.8) có thể được sử dụng trong một tên để tham khảo cho thực thể này. Một thực thể tuyên bố là một trong những điều sau đây:
...
Một biến cục bộ, một trong những điều sau đây:
* Một biến được khai báo trong một khối (§14.4)
* Một biến được khai báo trong câu lệnh for (§14.14)

Ví dụ đầu tiên của bạn là tuyên bố i trong một khối (được biểu thị bằng dấu ngoặc nhọn). Thứ hai của bạn không phải là, cũng không phải là một tuyên bố for.

Đã chỉnh sửa để thêm: Điều này làm cho ý nghĩa của cộng đồng. Nếu nó được cho phép, nó sẽ là vô dụng. Nó sẽ ngay lập tức rơi ra khỏi phạm vi.

+1

Tôi biết rằng đó là vô ích. Nhưng tôi muốn biết quy tắc đằng sau nó là gì. Và tôi có quan điểm của bạn là Brian. Thanx. – namalfernandolk

+5

JLS (Java Language Spec) luôn luôn là nơi để đi :) Thành thật mà nói nó là một số công cụ bạn học chỉ đọc mặc dù các phần của nó trong thời gian rảnh rỗi của bạn; Tôi biết tôi đã học được rất nhiều điều mà tôi sẽ không biết. –

+2

Trên thực tế, câu lệnh thứ hai sẽ khai báo biến cục bộ trong khối chứa câu lệnh 'for', vì vậy phần này của JLS không áp dụng. Câu trả lời của Daniel chỉ ra lý do thực sự tại sao cú pháp này không hợp lệ. – Joni

12

Điều này là do nó không phải là mã hữu ích. Nếu bạn có câu lệnh if không có dấu ngoặc nhọn ({}), chỉ dòng/câu lệnh đầu tiên sau khi được thực thi. Vì vậy, nếu bạn chỉ khai báo một biến địa phương, nó không thể được sử dụng bất cứ nơi nào khác. Vì vậy, tuyên bố nó là hoàn toàn thừa.

if(proceed){ 
int i= 0; 
// variable i can be used here 
//... 
} 

if (proceed) int i; // i can not be used anywhere as it is a local variable 
+0

Điều này là hợp lý giải thích –

53

Từ Java Language Spec.

 
    Block: 
      { BlockStatementsopt } 

    BlockStatements: 
      BlockStatement 
      BlockStatementsBlockStatement 

    BlockStatement: 
      LocalVariableDeclarationStatement 
      ClassDeclaration 
      Statement 

 
    IfThenStatement: 
      if (Expression) Statement 

Dường như int i là một LocalVariableDeclarationStatement, không phải là một Statement. Vì vậy, nó không hoạt động.

+16

+1. Đây là lý do thực sự cú pháp không hợp lệ. Phần JLS trên các tờ khai được đề cập trong câu trả lời của Brian có liên quan nhưng không phải là lý do thực sự. – Joni

3

nếu (tiếp tục) int i;

Nếu chúng tôi sử dụng tuyên bố if không có niềng răng, nó sẽ chỉ thực hiện dòng đầu tiên với if theo cách có điều kiện. Các dòng khác sẽ thực thi bình thường.

Đây là trình biên dịch thất bại, vì khai báo biến cục bộ xảy ra với cách điều kiện và trình biên dịch giả định nó không thể truy cập được với câu lệnh sai.

Nếu bạn sử dụng dấu ngoặc nhọn, sau đó khai báo biến và sử dụng biến cục bộ trong khối và do đó trình biên dịch giả định đó là mã có thể truy cập. Sau đó, không có lỗi trình biên dịch.

+0

Trình biên dịch * định nghĩa * rằng nó không thể truy cập được, và vì phạm vi của nó đã kết thúc, không phải vì tuyên bố có thể là sai. – EJP

0

Như trong Java/C++, nếu chúng ta viết nếu không có dấu ngoặc, chỉ có câu lệnh 1 được thực hiện Trong trường hợp này, biến i không được sử dụng.Bạn đang tuyên bố nó trong câu lệnh if và phạm vi của nó kết thúc sau tuyên bố này, đó là vô ích

Trong C++, điều này được phép, nhưng Java không cho phép

+0

Thanx abhi120, tôi biết rằng nó là vô dụng. Nhưng tôi muốn biết quy tắc đằng sau nó là gì. Xem câu trả lời của Brian Roach. – namalfernandolk

+0

Nhân tiện, tôi không phải là người đã bỏ phiếu bình chọn cho câu trả lời của bạn abhi120. :) – namalfernandolk

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