"Loop:" trong mã Java. Đây là gì, và tại sao nó biên dịch?


113

Đoạn mã này chỉ khiến tôi nhìn chằm chằm vào màn hình trong vài phút:

loop:
for (;;) {
    // ...
}

( dòng 137 ở đây )

Tôi chưa bao giờ thấy điều này trước đây và tôi không biết Java có từ khóa "vòng lặp" (NetBeans thậm chí không tô màu nó như một từ khóa) và nó biên dịch tốt với JDK 6.

Giải thích là gì?

Câu trả lời:


205

Nó không phải là một keywordnó là một label.

Sử dụng:

    label1:
    for (; ; ) {
        label2:
        for (; ; ) {
            if (condition1) {
                // break outer loop
                break label1;
            }
            if (condition2) {
                // break inner loop
                break label2;
            }
            if (condition3) {
                // break inner loop
                break;
            }
        }
    }

Tài liệu .


19
Đáng nói hơn, vì OP có thể không quen với khái niệm goto / label, nên nó thường được coi là một thực hành xấu, ngoại trừ trong những tình huống rất cụ thể (ví dụ: để tắt nhiều vòng lồng nhau).
haylem

10
@haylem true, nhưng tôi sẽ đi xa hơn: nhiều vòng lặp lồng nhau thường là một phương pháp không tốt. Bất cứ khi nào tôi sử dụng nhãn vòng lặp, cuối cùng tôi đã cấu trúc lại mã để tôi không cần chúng. Luôn luôn có một cách tốt hơn thế.
Sean Patrick Floyd

73

Như các áp phích khác đã nói, đó là nhãn, không phải từ khóa. Sử dụng nhãn cho phép bạn làm những việc như:

outer: for(;;) {
   inner: for(;;) {
     break outer;
   }
}

Điều này cho phép phá vỡ vòng lặp bên ngoài.

Liên kết đến tài liệu .


31

Câu hỏi đã được trả lời, nhưng như một lưu ý phụ:

Tôi đã nghe nói về câu hỏi phỏng vấn "Tại sao mã Java này lại hợp lệ?" (loại bỏ ví dụ đơn giản hơn; đây là ví dụ nhỏ hơn, thx Tim Büthe):

url: http://www.myserver.com/myfile.mp3
downLoad(url);

Các bạn có biết mã này là gì không?

Giải pháp: hai nhãn urlhttp, một chú thích www.myserver.com/myfile.mp3và một cuộc gọi phương thức với một tham số có cùng tên ( url) với nhãn. Đúng, điều này sẽ biên dịch (nếu bạn xác định lệnh gọi phương thức và biến cục bộ ở nơi khác).


FYI bạn không cần vòng lặp, a; ở dòng tiếp theo là đủ
Tim Büthe 29/09/10

Cảm ơn vì đã nhắc nhở tôi, tôi nghĩ không có vòng lặp nào trong câu hỏi. Tôi sẽ sửa câu trả lời của tôi (Tôi đã không bao giờ hỏi câu hỏi này, nhưng người phỏng vấn là một đồng nghiệp cũ của tôi)
Sean Patrick Floyd

16

Đó không phải là một từ khóa, đó là một nhãn. Nó có nghĩa là được sử dụng với breakcontinuetừ khóa bên trong các vòng lặp lồng nhau:

outer:
for(;;){
    inner:
    for(;;){
        if(){
            break inner; // ends inner loop
        } else {
            break outer; // ends outer loop
        }
    }
}

innernhãn là vô ích ở đây, break;là đủ
gertas

12
Nếu có hai cách để phá vỡ vòng lặp, tôi đánh giá cao innernhãn vì sự rõ ràng.
Steve Jackson

1
@gertas: Tôi nghĩ anh ấy chỉ đang chứng minh quan điểm. Nhưng theo Steve Jackson, dù sao cũng nên nói điều đó với mục đích tự làm tài liệu.
Jay

5

Nó không phải là một từ khóa; đó là một nhãn hiệu .

Nó cho phép bạn đi một nhãn breakvà dán nhãn continue.


4

Đây thực sự là câu trả lời cho nhận xét của seanizer về câu trả lời của org.life.java, nhưng tôi muốn nhập một số mã nên không thể sử dụng tính năng nhận xét.

Mặc dù rất hiếm khi tôi tìm thấy cách sử dụng cho "break label", nhưng nó vẫn xảy ra một cách ngẫu nhiên. Trường hợp phổ biến nhất là khi tôi đang tìm kiếm thứ gì đó nằm trong cấu trúc yêu cầu một vòng lặp lồng nhau để tìm kiếm, như:

search:
for (State state : stateList)
{
  for (City city : state.cityList)
  {
    if (city.zipcode.equals(wantZip))
    {
      doSomethingTo(city);
      break search;
    }
  }
}

Thông thường trong những trường hợp như vậy, tôi đẩy toàn bộ nội dung vào một chương trình con để khi có một lần truy cập, tôi có thể trả về đối tượng đã tìm thấy và nếu nó rơi ra cuối vòng lặp, tôi có thể trả về null để cho biết không tìm thấy hoặc có thể ném một ngoại lệ. Nhưng điều này đôi khi hữu ích.

Thành thật mà nói, tôi nghĩ những người phát minh ra Java đã bao gồm tính năng này vì giữa tính năng này và việc xử lý ngoại lệ, họ đã loại bỏ hai cách sử dụng hợp pháp cuối cùng cho GOTO.

Phụ lục rất muộn:

Tôi đã thấy một dòng mã tuyệt vời một lần. Lập trình viên đã viết:

http://www.example.com/xyz.jsp
for (Foo foo1 : foolist)

Anh ấy không thực sự nói "example.com" mà là trang web của công ty chúng tôi.

Nó tạo ấn tượng rằng có một URL trong mã. Nó biên dịch thành công, giống như nó làm một cái gì đó. Nhưng ... nó làm được gì?

Trong thực tế, nó không làm gì cả. "http:" là nhãn mà anh ấy không bao giờ tham chiếu. Sau đó, "//" làm cho phần còn lại của dòng trở thành một nhận xét.


4

Đó là một nhãn điểm ngắt, để cho phép bạn thoát ra khỏi một vòng lặp được chỉ định, thay vì chỉ đơn giản là vòng trong cùng mà bạn tình cờ gặp phải.

Nó được sử dụng trên dòng 148 .



2

Đó là một nhãn, mặc dù hãy xem ví dụ sau:

int a = 0;
int b = 0
while (a<10){
    firstLoop:
    a++;
    while(true){
        b++
        if(b>10){
            break firstLoop;
        }
    }
 }

Khi b>10luồng thực thi đi đến vòng lặp ngoài.



1

Nó không phải là một từ khóa, mà là một nhãn . Nếu bên trong forvòng lặp bạn viết break loop;, và bạn thoát khỏi vòng lặp đó.


0

Nó là một nhãn. Nói chung là một nhãn được sử dụng trong Java để chuyển luồng điều khiển ở vị trí mong muốn trong khi tất cả các từ khóa, như tiếp tục và ngắt, có một lựa chọn vị trí cụ thể.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.