Câu trả lời:
Từ Đặc tả ngôn ngữ Java - 15,26.2 Toán tử chuyển nhượng hợp chất .
Một biểu thức gán tổng hợp của biểu mẫu
E1 op= E2
tương đương vớiE1 = (T)((E1) op (E2))
, trong đóT
là loạiE1
, ngoại trừ chỉE1
được đánh giá một lần.
Như vậy a &= b;
là tương đương với a = a & b;
.
(Trong một số cách sử dụng, việc tạo kiểu tạo ra sự khác biệt cho kết quả, nhưng trong trường hợp này b
phải có boolean
và việc tạo kiểu không làm gì cả.)
Và, đối với bản ghi, a &&= b;
không phải là Java hợp lệ. Không có &&=
nhà điều hành.
Trong thực tế, có rất ít sự khác biệt về ngữ nghĩa giữa a = a & b;
và a = a && b;
. (Nếu b
là một biến hoặc một hằng số, kết quả sẽ giống nhau cho cả hai phiên bản. Chỉ có một sự khác biệt về ngữ nghĩa khi b
một biểu hiện phụ có tác dụng phụ. Trong &
trường hợp, hiệu ứng phụ luôn xảy ra. &&
trường hợp nó xảy ra tùy thuộc vào giá trị của a
.)
Về mặt hiệu suất, sự đánh đổi nằm giữa chi phí đánh giá b
và chi phí kiểm tra và chi nhánh của giá trị a
và khả năng tiết kiệm để tránh việc chuyển nhượng không cần thiết a
. Phân tích không đơn giản, nhưng trừ khi chi phí tính toán b
là không tầm thường, sự khác biệt hiệu năng giữa hai phiên bản là quá nhỏ không đáng để xem xét.
xem 15.22.2 của JLS . Đối với toán hạng boolean, &
toán tử là boolean, không phải bitwise. Sự khác biệt duy nhất giữa &&
và &
đối với các toán hạng boolean là vì &&
nó được ngắn mạch (có nghĩa là toán hạng thứ hai không được đánh giá nếu toán hạng thứ nhất đánh giá là sai).
Vì vậy, trong trường hợp của bạn, nếu b
là một, nguyên thủy a = a && b
, a = a & b
và a &= b
tất cả làm điều tương tự.
Đây là cái cuối cùng:
a = a & b;
Đây là một cách đơn giản để kiểm tra nó:
public class OperatorTest {
public static void main(String[] args) {
boolean a = false;
a &= b();
}
private static boolean b() {
System.out.println("b() was called");
return true;
}
}
b() was called
Do đó, đầu ra là toán hạng bên phải được đánh giá.
Vì vậy, như đã được đề cập bởi những người khác, a &= b
cũng giống như a = a & b
.
tôi đã gặp một tình huống tương tự bằng cách sử dụng booleans nơi tôi muốn tránh gọi b () nếu a đã sai.
Điều này làm việc cho tôi:
a &= a && b()
a=a&&b()
.