2010-03-27 17 views
5

Mã Java Sau đây là ném một lỗi biên dịch:Odd lỗi biên dịch trên if-khoản mà không cần niềng răng

if (checkGameTitle(currGame)) 
    ArrayList<String> items = parseColumns(tRows.get(rowOffset+1), currGame, time, method); 

checkGameTitle là một hàm public static, trả lại một boolean. Các lỗi là tất cả các loại "không thể tìm thấy biểu tượng" với các ký hiệu là variable ArrayList, variable Stringvariable items.

Tuy nhiên, nếu tôi thêm {dấu ngoặc nhọn} thì biên dịch mã không bị lỗi. Tại sao điều này có thể? Có một số sự mơ hồ về các điều khoản if mà không có chúng?

Trả lời

11

Nếu bạn khai báo biến số items tại thời điểm này, không thể truy cập từ bất kỳ đâu. Vì vậy, nó sẽ không có ý nghĩa để cho phép cấu trúc này.

OTOH, khi bạn mở một khối, nó vẫn không có ý nghĩa để làm điều tương tự (lúc đầu). Nhưng nó được mong đợi, rằng bạn sẽ muốn mở rộng khối sau này, và rằng nó cuối cùng sẽ có ý nghĩa.

+5

+1 - ngữ pháp của Java đang ngăn lỗi lập trình. Xem: http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html Điều này nêu bật tầm quan trọng của ngữ pháp được xác định rõ như Java. –

0

Bạn đang xác định biến items trong câu lệnh if, vì vậy sẽ không thể sử dụng được ở bất kỳ đâu ngoài phạm vi đó.

CHỈNH SỬA: Quá chậm ...

4

Với dấu ngoặc nhọn, bạn tạo khối có thể chứa khai báo. Nếu không có niềng răng, bạn chỉ có thể có một tuyên bố, không phải là một tuyên bố, chẳng hạn như ví dụ của bạn

1

Vấn đề là điều này:

if (condition) 
    ArrayList<String> items = ...; 

... là về cơ bản tương đương như sau:

if (condition) { 
    ArrayList<String> items = .; 
} 

Bạn đã xác định và khởi tạo items, nhưng khi bạn thoát khỏi câu lệnh/khối đó nằm ngoài phạm vi, vì vậy bạn không thể sử dụng nó cho bất kỳ thứ gì. Trình biên dịch cảnh báo bạn về điều đó.

0

Lỗi trình biên dịch là do các quy tắc của ngôn ngữ không đưa ra một điểm rõ ràng về phạm vi khai báo biến của "mục".

Ví dụ, nếu tôi có một khối mã như thế này:

bool isTrue() { 
    bool returnValue = false; 
    if (cheese.isGreen()) { 
    returnValue = true; 
    } 
    return returnValue; 
} 

nó là đau đớn rõ ràng rằng returnValue là một biến có giá trị trên toàn bộ phương pháp.

Nếu tôi có một khối mã như thế này:

bool isTrue() { 
    if (cheese.isGreen()) { 
    bool returnValue = true; 
    } 
    return returnValue; 
} 

nó là đau đớn rõ ràng rằng returnValue không hợp lệ bên ngoài của "mệnh đề if".

Nhưng nếu tôi có một khối mã như thế này:

bool isTrue() { 
    if (cheese.isGreen()) 
    bool returnValue = true; 
    return returnValue; 
} 

nó không phải là rõ ràng nếu returnValue là trong phạm vi của câu lệnh if hoặc nếu returnValue là trong phạm vi toàn bộ phương pháp. Điều này là do các chi tiết về cách bố trí ngữ pháp ngôn ngữ Java.Về cơ bản, nó được phép khai báo các biến mới trong bất kỳ khối nào (vì một khối xác định rõ phạm vi của biến) nhưng câu lệnh if này không chứa một khối.

Nếu bạn cho rằng Java thêm khối cho bạn một cách âm thầm, thì phạm vi nằm trong "khối bị lãng quên". Nếu bạn giả định rằng vì không có khối rõ ràng để chứa phạm vi, thì phạm vi của biến ở cùng mức với phần còn lại của phương thức. Các lập luận rất nhiều vì quan điểm đó là "chính xác hơn", vì vậy toàn bộ nỗ lực làm một điều như vậy đều bị cấm. Nếu điều này có vẻ kỳ quặc đối với bạn, và bạn chỉ thấy một người điên không cho rằng biến được định nghĩa trong phạm vi của một khối ngụ ý, hãy nhớ rằng có những ngôn ngữ trước Java, nơi phạm vi sẽ là ở cùng cấp với tuyên bố trả về. Vâng, các ngôn ngữ điên rồ theo tiêu chuẩn ngày nay, nhưng chúng vẫn tồn tại.

2

Chỉ vì tôi nghĩ rằng nó luôn luôn hữu ích trong những tình huống này, phần liên quan của ngôn ngữ Java Specification đây là §14.4:

Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.

Nói cách khác, các biến địa phương tuyên bố chỉ có thể xuất hiện như tuyên bố độc lập ở cấp ngay lập tức 'bên dưới' một khối ({}). Chúng không được tính là Statements (§14.5), là những thứ sau if (....).

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