2012-01-31 31 views
10

Xem xét chức năng này:Thứ tự từ trái sang phải của các hoạt động được bảo đảm trong Java?

public static final int F(int a, int b) { 
    a = a - 1 + b; 
    // and some stuff 
    return a; 
} 

Có cần thiết cho việc triển khai của các JVM để thực hiện - 1 trước + b?

Nếu chúng tôi có hồ sơ hệ thống được đính kèm với JVM, chúng tôi có thấy hoạt động + b đang được thực hiện trước hoạt động + 1 không?

+0

Không có liên quan, nhưng 'đầu vào' là gì? –

+0

@SoboLAN lỗi typo .. – Pacerier

+1

@Pacerier - đây không phải là [Ngắn, Tự chứa, Sửa (Compilable), Ví dụ] (http://sscce.org). Nó không phải là khép kín (không có lớp xe hơi, cũng không phải chính). Nó không phải là compoeable (nó có chứa một lỗi đánh máy - bạn đã sao chép và dán này?). –

Trả lời

6

Thực ra, tôi sẽ không đồng ý với phần còn lại của câu trả lời. JLS §15.7 mà mọi người đang đề cập đến để thảo luận về việc đánh giá các toán hạng. Tức là, trong biểu thức

x = foo() - 1 + bar() 

, trong đó thứ tự các phương thức sẽ được gọi.

Các phần có liên quan là §15.7.3, trong đó nêu rõ

An thực hiện không có thể tận dụng lợi thế của bản sắc đại số như luật kết hợp để viết lại biểu thức thành một trật tự tính toán thuận tiện hơn trừ nó có thể được chứng minh rằng biểu thức thay thế là tương đương về giá trị và trong các tác dụng phụ có thể quan sát nó [...]

Từ ngày Biểu thức e x = x - 1 + q tương đương với tất cả các cách để x = x + q - 1, việc triển khai tuân thủ được phép viết lại biểu thức (nếu vì lý do nào đó nên quyết định đó là hiệu quả hơn).

+0

@Pacerier, ghi chú sau đây. Nói chung, 'foo()' có thể ảnh hưởng đến 'bar()', do đó JVM nên tôn trọng thứ tự. Tương tự cho 'i> 0 && x/i> 3'. Về mặt đại số, 'a && b' tương đương với' b && a' nhưng có 'i> 0' trước tiên tránh NPE trong biểu thức thứ hai. – rdllopes

2

Theo here:

nhà khai thác trên cùng một dòng có độ ưu tiên bằng nhau. Khi nhà khai thác của ưu tiên bằng nhau xuất hiện trong cùng một biểu thức, quy tắc phải chi phối được đánh giá trước tiên. Tất cả các toán tử nhị phân ngoại trừ các toán tử gán được đánh giá từ trái sang phải; phân công toán tử được đánh giá từ phải sang trái.

Vì vậy, có.

2

Có, mặc dù câu hỏi lớn hơn có thực sự quan trọng không? Phép trừ và phép cộng có cùng mức ưu tiên trong bất kỳ phép toán khoa học nào và có thể thay đổi được. Đó là:

x = đầu vào - 1 + q;

giống với

x = đầu vào + q - 1;

+0

Tôi có nghĩa là tôi không thích nó khi nó tràn, nhưng nghĩ về nó ngay cả khi nó tràn, kết quả là như nhau .. – Pacerier

+0

Đúng, nhưng cả hai cách bạn có thể bị tràn - tức là: nếu đầu vào là MIN_INTEGER hoặc q + input = MAX_INTEGER. Không có cách nào thực sự để bảo vệ chống lại điều đó trong ví dụ của bạn. –

1

Có nó sẽ luôn luôn, mặc dù nó sẽ không ảnh hưởng đến kết quả của việc thêm/trừ đi.

7

Có, bằng ngôn ngữ Java specification, §15.7.

Ngôn ngữ lập trình Java đảm bảo rằng toán hạng của toán tử xuất hiện được đánh giá theo thứ tự cụ thể, từ trái sang phải.

Chúng tôi khuyên rằng mã không nên dựa chủ yếu vào đặc điểm kỹ thuật này. Mã thường rõ ràng hơn khi mỗi biểu thức chứa tối đa một hiệu ứng phụ, như hoạt động ngoài cùng của nó và khi mã không phụ thuộc vào chính xác ngoại lệ nào phát sinh như là hệ quả của việc đánh giá các biểu thức từ trái sang phải.

+0

"Xuất hiện để được đánh giá" - liệu Java có quy tắc "as-if", tương tự như các tiêu chuẩn C và C++ không? Cụ thể là JVM được phép làm bất cứ điều gì nó muốn, miễn là điều đó không thể phân biệt được với hành vi của tiêu chuẩn? –

+2

@Rob Vâng, đúng vậy. Nó có thể thực hiện các thao tác theo bất kỳ thứ tự nào xuất hiện * đối với chuỗi thực thi * như thể chúng được thực hiện theo thứ tự được chỉ định. Tuy nhiên, theo quan điểm của các chủ đề khác, chúng có thể xuất hiện không đúng thứ tự. Đó là lý do tại sao nhiều luồng phải phối hợp bằng các rào cản bộ nhớ được xác định rõ. – erickson

1

Nó thực sự không phải là triển khai JVM quan trọng, vì chúng chỉ thực thi danh sách các hướng dẫn từ tệp lớp.

2

Bạn có thể thấy ở đây ưu tiên toán tử trong Java: http://bmanolov.free.fr/javaoperators.php.Bởi vì +- có cùng mức độ ưu tiên, chúng sẽ được thực thi theo thứ tự xuất hiện của chúng.

Nếu bạn muốn trở thành rõ ràng hơn về những gì mà hoạt động diễn ra đầu tiên (hoặc nếu bạn muốn phá vỡ được xây dựng trong ưu tiên) parantheses, bạn có thể (và nên) sử dụng (()), như thế này:

x = (a - b) + (c * (d - e))

1

Dường như với tôi sẽ luôn có một tác dụng phụ khi thực hiện X + q - 1 Khi bạn nên thực hiện X - 1 + q.

Khi tổng x + q vượt quá Bignum bằng 1, việc thực hiện từ trái sang phải sẽ thành công ... Việc thực thi ngoài trật tự sẽ tạo ra tràn.

Vì vậy, việc thực hiện lệnh không có hiệu lực phụ.

Trừ khi các bẫy thực hiện không theo thứ tự tự tràn, sau đó thực hiện lại phép tính theo thứ tự đúng khi cần thiết để tránh tác dụng phụ.

0

Quan trọng cần thêm ở đây là java không có ưu tiên hàng đầu cho các toán tử có vẻ dựa trên thứ tự số học cơ bản của các phép toán. Để biết danh sách ưu tiên đầy đủ, hãy xem source

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