Toán tử Java & = có áp dụng & hoặc && không?


139

Giả định

boolean a = false;

Tôi đã tự hỏi nếu làm:

a &= b; 

tương đương với

a = a && b; //logical AND, a is false hence b is not evaluated.

hoặc mặt khác nó có nghĩa là

a = a & b; //Bitwise AND. Both a and b are evaluated.

Câu trả lời:


146

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= E2tương đương với E1 = (T)((E1) op (E2)), trong đó Tlà loại E1, 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 bphải có booleanvà 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;a = a && b;. (Nếu blà 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 bmộ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á bvà chi phí kiểm tra và chi nhánh của giá trị avà 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 blà 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.


Đoạn "trong thực tế" của bạn là sai lệch. Lý do duy nhất để sử dụng & hơn && là để tính toán biểu hiện phụ không tầm thường trong "b"
AlexP

Làm rõ. (Trên thực tế, sự tầm thường không thực sự đi vào nó.)
Stephen C

51

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 &&&đố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 blà một, nguyên thủy a = a && b, a = a & ba &= btất cả làm điều tương tự.


2
Vậy (a & = b;) sẽ không bị đoản mạch nếu b là một cuộc gọi phương thức? có cái gì giống như toán tử "&& =" không?
is7s

2
Có vẻ như điều này không trả lời câu hỏi; OP đã biết về ngắn mạch.
HOẶC Mapper


0

Đâ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 calledDo đó, đầ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 &= bcũng giống như a = a & b.


-2

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()

25
Để tránh dư thừa (vẫn cho phép đoản mạch), bạn chỉ cần viết a=a&&b().
Unai Vivi
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.