2012-01-16 71 views
52

Sự khác nhau giữa vòng lặp tiêu chuẩn while(true)for(;;) là gì?Java: for (;;) so với while (true)

Có bất kỳ hoặc cả hai sẽ được ánh xạ tới cùng một bytecode sau khi biên dịch không?

+3

Bạn đã thử biên dịch và xem mã byte chưa? –

+3

Không có gì: http://stackoverflow.com/search?q=for+while+true –

+0

có thể trùng lặp của [for (; true;) khác nhau từ khi (true)?] (Http://stackoverflow.com/questions/ 440694/fortrue-different-from-whiletrue) –

Trả lời

88

Ngữ nghĩa, chúng hoàn toàn tương đương nhau. Đó là một vấn đề của hương vị, nhưng tôi nghĩ rằng while(true) trông sạch hơn, và dễ dàng hơn để đọc và hiểu ngay từ cái nhìn đầu tiên. Trong Java không phải của chúng gây ra cảnh báo trình biên dịch.

Ở cấp độ bytecode, nó có thể phụ thuộc vào trình biên dịch và mức tối ưu hóa, nhưng về nguyên tắc mã được phát ra phải giống nhau.

EDIT:

Mở trình biên dịch của tôi, sử dụng các plugin Bytecode Outline, các bytecode cho for(;;){} trông như thế này:

L0 
    LINENUMBER 6 L0 
    FRAME SAME 
    GOTO L0 

Và bytecode cho while(true){} trông như thế này:

L0 
    LINENUMBER 6 L0 
    FRAME SAME 
    GOTO L0 

Vì vậy, có, ít nhất là đối với tôi, chúng giống hệt nhau.

+5

Đã chấp nhận câu trả lời này vì đã cung cấp mã và cách mã được tra cứu. Cảm ơn bạn. :) – sjas

+1

cho (;;) là phiên bản sạch hơn, imo (cũng ngắn hơn: P) – bestsss

+1

Lưu ý rằng trong VS trong khi (true) gây cảnh báo biên dịch trên các cài đặt cao nhất cho C và C++ (C#?). Có lẽ không phải là một vấn đề đối với Java, nhưng nếu bạn viết bằng các ngôn ngữ khác đôi khi, 'for (;;)' là một thói quen tốt hơn để phát triển. –

3

Tùy thuộc vào trình biên dịch, nó sẽ ánh xạ tới cùng một mã byte.

2

JVM sẽ tìm cách tốt nhất để thực hiện bytecode và trong cả hai trường hợp cũng nên làm như vậy. Vì vậy, tôi nghĩ không có sự khác biệt. trong khi (đúng) chỉ đẹp hơn.

2

Chức năng không có sự khác biệt. Bất kỳ hiệu quả nào đạt được hoặc bị mất bởi một sự khác biệt trong bytecode có thể sẽ không đáng kể so với bất kỳ lệnh nào bạn sẽ chạy trong phần thân của vòng lặp.

5

Trên Oracle Java 7, bạn nhận được cùng một mã byte. Bạn không thể nói từ mã byte được sử dụng trong bản gốc. Đó là tốt nhất là một vấn đề của hương vị. Tôi sử dụng while(true)

20

Tùy thuộc vào bạn sẽ sử dụng loại nào. Nguyên nhân là bằng với trình biên dịch.

tạo file:

// first test 
public class Test { 
    public static void main(String[] args) { 
     while (true) { 
      System.out.println("Hi"); 
     } 
    } 
} 

biên dịch:

javac -g:none Test.java 
rename Test.class Test1.class 

tạo file:

// second test 
public class Test { 
    public static void main(String[] args) { 
     for (;;) { 
      System.out.println("Hi"); 
     } 
    } 
} 

biên dịch:

javac -g:none Test.java 
mv Test.class Test2.class 

so sánh:

diff -s Test1.class Test2.class 
Files Test1.class and Test2.class are identical 
+4

upvote cho phương pháp được sử dụng. – sjas

+0

Tôi đã làm một bài kiểm tra nhỏ. Việc biên dịch lại các lớp trong jd-gui cho thấy 'for (;;)' và NOT 'whilte (true)' cho cả hai lớp! – vedi0boy

+0

@ vedi0boy ở cấp JVM (và bytecode) - không có sự khác biệt, jd-gui chọn cách dễ nhất để hiển thị vòng lặp này. – 4ndrew

2

Tôi đã xem xét các mã byte được tạo ra và phát hiện ra rằng kể từ khi tình trạng này luôn luôn là đúng (tại thời gian biên dịch), trình biên dịch sẽ biên dịch đi kiểm tra và chỉ chi nhánh luôn luôn trở lại đầu vòng lặp. Tôi giả định rằng một tuyên bố tiếp tục cũng sẽ thực hiện một nhánh luôn quay lại đầu vòng lặp.Vì vậy, không chỉ không tạo ra bất kỳ sự khác biệt nào, thậm chí không có mã nào được tạo ra để kiểm tra bất kỳ thứ gì.

3

Nó biên dịch xuống cùng một mã byte và đó là vấn đề về hương vị mà bạn thích.

Tôi đọc rất nhiều mã nguồn từ JDK được phân phối Oracle, và tôi không thể dễ dàng nhớ rằng tôi đã nhìn thấy câu lệnh while(true) trong mã của họ, nhưng tôi đã thấy toàn bộ câu lệnh for(;;) trong mã của họ. Cá nhân tôi, tôi ủng hộ for(;;) và lý do của tôi diễn ra một chút như sau:

Vòng lặp while "nên" yêu cầu biểu thức boolean, không phải là hằng số boolean. while(true) là một chút như if(true), cả hai mà tôi nghĩ rằng đã được thực hiện hợp pháp chỉ cho sự thoải mái thêm của quần chúng. Một số trống while() không biên dịch. Thêm true vào đó có cảm giác giống như hack.

for(;;) mặt khác là "vòng lặp thực", mặc dù là một vòng trống. Ngoài ra, nó giúp bạn tiết kiệm một vài tổ hợp phím! =) (không phải là nó quan trọng)

Vì vậy, và tôi biết nó nghe có vẻ điên rồ, nhưng mặc dù (true) đọc tốt hơn bằng tiếng Anh, tôi nghĩ (;;) thể hiện rõ hơn ý định của bạn và giống như ngôn ngữ lập trình Java. Các vòng lặp vĩnh cửu nên tránh được. Khi tôi đọc (;;), tôi cảm thấy an toàn khi biết nhà phát triển sẽ phanh đường dẫn thực hiện ở đâu đó. Khi tôi đọc trong khi (đúng), tôi không thể chắc chắn nữa. Nhưng này, có lẽ đó chỉ là tôi! Tất cả chúng ta đều được tự do lựa chọn hương vị riêng của mình.

+0

Hơn bạn có thể viết trong khi (1 == 1), theo ý kiến ​​của tôi, cách sạch sẽ nhất. – JacksOnF1re

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