Tôi không chắc chắn nếu có một mục trong Đặc tả ngôn ngữ Java chỉ ra việc tải giá trị trước đó của một biến ...
Có. Lần tới khi bạn không rõ thông số kỹ thuật nói gì, vui lòng đọc thông số kỹ thuật và sau đó đặt câu hỏi nếu nó không rõ ràng.
... bên phải (x = y)
, theo thứ tự ngụ ý trong ngoặc, nên được tính toán trước.
Tuyên bố đó là sai. Dấu ngoặc đơn không ngụ ý một thứ tự đánh giá . Trong Java, thứ tự đánh giá được chuyển từ trái sang phải, bất kể dấu ngoặc đơn. Dấu ngoặc đơn xác định vị trí của ranh giới phụ, không phải thứ tự đánh giá.
Tại sao biểu thức thứ nhất đánh giá là sai, nhưng biểu thức thứ hai đánh giá là đúng?
Quy tắc cho ==
toán tử là: đánh giá bên trái để tạo ra một giá trị, đánh giá bên phải để tạo ra một giá trị, so sánh các giá trị, so sánh là giá trị của biểu thức.
Nói cách khác, ý nghĩa của expr1 == expr2
nó luôn giống như bạn đã viết temp1 = expr1; temp2 = expr2;
và sau đó đánh giátemp1 == temp2
.
Quy tắc cho =
toán tử có biến cục bộ ở phía bên trái là: đánh giá phía bên trái để tạo biến, đánh giá phía bên phải để tạo giá trị, thực hiện phép gán, kết quả là giá trị được gán.
Vì vậy, đặt nó cùng nhau:
x == (x = y)
Chúng tôi có một toán tử so sánh. Đánh giá bên trái để tạo ra một giá trị - chúng tôi nhận được giá trị hiện tại của x
. Đánh giá bên phải: đó là một nhiệm vụ để chúng tôi đánh giá bên trái để tạo ra một biến - biến x
- chúng tôi đánh giá bên phải - giá trị hiện tại của y
- gán nó cho x
, và kết quả là giá trị được gán. Sau đó chúng tôi so sánh giá trị ban đầu của x
giá trị được gán.
Bạn có thể làm (x = y) == x
như một bài tập. Một lần nữa, hãy nhớ rằng, tất cả các quy tắc để đánh giá bên trái xảy ra trước tất cả các quy tắc đánh giá bên phải .
Tôi đã dự kiến (x = y) sẽ được đánh giá trước, và sau đó nó sẽ so sánh x với chính nó (3) và trả về giá trị true.
Kỳ vọng của bạn dựa trên một tập hợp niềm tin không chính xác về các quy tắc của Java. Hy vọng rằng bây giờ bạn có niềm tin chính xác và sẽ trong tương lai mong đợi những điều thực sự.
Câu hỏi này khác với "thứ tự đánh giá các biểu hiện phụ trong biểu thức Java"
Tuyên bố này là sai. Câu hỏi đó hoàn toàn phù hợp.
x chắc chắn không phải là một 'subexpression' ở đây.
Tuyên bố này cũng sai. Đó là một biểu hiện phụ hai lần trong mỗi ví dụ.
Nó cần được tải để so sánh chứ không phải là 'đánh giá'.
Tôi không biết cái này nghĩa là gì.
Rõ ràng bạn vẫn còn nhiều niềm tin sai lầm. Lời khuyên của tôi là bạn đọc đặc tả cho đến khi niềm tin sai lầm của bạn được thay thế bằng niềm tin thực sự.
Câu hỏi là dành riêng cho Java và biểu thức x == (x = y), không giống như các cấu trúc không thực tế có tầm nhìn xa thường được tạo ra cho các câu hỏi phỏng vấn khó, đến từ một dự án thực tế.
Nguồn gốc của biểu thức không liên quan đến câu hỏi. Các quy tắc cho các biểu thức như vậy được mô tả rõ ràng trong đặc tả; đọc nó!
Nó được cho là một thay thế một dòng cho thành ngữ so sánh và thay thế
Vì sự thay thế một dòng đó gây ra sự nhầm lẫn lớn trong bạn, người đọc mã, tôi sẽ đề nghị rằng đó là một lựa chọn kém. Làm cho mã ngắn gọn hơn nhưng khó hiểu hơn không phải là một chiến thắng. Nó không có khả năng làm cho mã nhanh hơn.
Ngẫu nhiên, C # đã so sánh và thay thế như một phương thức thư viện, có thể được đưa vào một hướng dẫn máy. Tôi tin rằng Java không có một phương thức như vậy, vì nó không thể được biểu diễn trong hệ thống kiểu Java.