Các câu trả lời khác đã thực hiện tốt việc bao gồm sự khác biệt về chức năng giữa các toán tử, nhưng các câu trả lời có thể áp dụng cho mọi ngôn ngữ có nguồn gốc C duy nhất tồn tại ngày nay. Câu hỏi được gắn thẻjavavà vì vậy tôi sẽ cố gắng trả lời cụ thể và kỹ thuật cho ngôn ngữ Java.
&và |có thể là Toán tử bitwise Integer hoặc Toán tử logic Boolean. Cú pháp của các toán tử bitwise và logic ( §15,22 ) là:
AndExpression:
EqualityExpression
AndExpression & EqualityExpression
ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression ^ AndExpression
InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression | ExclusiveOrExpression
Cú pháp cho EqualityExpressionđược định nghĩa trong §15,21 , yêu cầu RelationalExpressionđược xác định trong §15.20 , lần lượt yêu cầu ShiftExpressionvà ReferenceTypeđược xác định trong §15.19 và §4.3 , tương ứng. ShiftExpressionyêu cầu AdditiveExpressionđược xác định trong §15,18 , tiếp tục đi sâu vào, xác định số học cơ bản, toán tử đơn nguyên, v.v. ReferenceTypeđi sâu vào tất cả các cách khác nhau để biểu diễn một loại. (Mặc dù ReferenceTypekhông bao gồm các kiểu nguyên thủy, định nghĩa về các kiểu nguyên thủy cuối cùng là bắt buộc, vì chúng có thể là kiểu thứ nguyên cho một mảng, là một ReferenceType.)
Các toán tử Bitwise và Logical có các thuộc tính sau:
- Các toán tử này có quyền ưu tiên khác nhau, với
&quyền ưu tiên cao nhất và |quyền ưu tiên thấp nhất.
- Mỗi toán tử này được liên kết trái cú pháp (mỗi nhóm từ trái sang phải).
- Mỗi toán tử là giao hoán nếu các biểu thức toán hạng không có tác dụng phụ.
- Mỗi toán tử là liên kết.
- Các toán tử bitwise và logic có thể được sử dụng để so sánh hai toán hạng loại hoặc hai toán hạng loại
boolean. Tất cả các trường hợp khác dẫn đến một lỗi thời gian biên dịch.
Sự khác biệt giữa việc toán tử đóng vai trò là toán tử bitwise hay toán tử logic phụ thuộc vào việc toán hạng có "chuyển đổi thành kiểu tích phân nguyên thủy" ( §4.2 ) hay nếu chúng thuộc loại booleanhoặc Boolean( §5.1.8 ).
Nếu các toán hạng là loại tích phân, thì việc thăng cấp số nhị phân ( §5.6.2 ) được thực hiện trên cả hai toán hạng, để lại cả hailong hoặc ints cho hoạt động. Kiểu của hoạt động sẽ là loại toán hạng (được thăng cấp). Tại thời điểm đó, &sẽ là bitwise AND, ^sẽ độc quyền bitwise OR và |sẽ được bao gồm bitwise OR. ( §15.22.1 )
Nếu các toán hạng là booleanhoặc Boolean, các toán hạng sẽ phải chuyển đổi unboxing nếu cần thiết ( §5.1.8 ), và loại hoạt động sẽ là boolean. &sẽ dẫn đến truenếu cả hai toán hạng là true, ^sẽ dẫn đến truenếu cả hai toán hạng khác nhau và| sẽ dẫn đến truenếu một toán hạng là true. ( §15.22.2 )
Ngược lại, && là "Toán tử có điều kiện và" ( §15,23 ) và ||là "Toán tử có điều kiện-hoặc" §15.24 ). Cú pháp của chúng được định nghĩa là:
ConditionalAndExpression:
InclusiveOrExpression
ConditionalAndExpression && InclusiveOrExpression
ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression || ConditionalAndExpression
&& giống như & , ngoại trừ việc nó chỉ đánh giá toán hạng bên phải nếu toán hạng bên trái là true. ||giống như |, ngoại trừ việc nó chỉ đánh giá toán hạng bên phải nếu toán hạng bên trái là false.
Có điều kiện-Và có các thuộc tính sau:
- Toán tử có điều kiện và toán tử được liên kết từ trái sang phải (nhóm này từ trái sang phải).
- Toán tử có điều kiện và hoàn toàn liên quan đến cả tác dụng phụ và giá trị kết quả. Đó là, đối với bất kỳ biểu thức
a, bvà c, đánh giá của biểu thức ((a) && (b)) && (c)tạo ra kết quả tương tự, với các tác dụng phụ tương tự xảy ra theo thứ tự, như đánh giá của biểu thức (a) && ((b) && (c)).
- Mỗi toán hạng của toán tử có điều kiện và phải có kiểu
booleanhoặc hoặc Booleanxảy ra lỗi thời gian biên dịch.
- Kiểu của một điều kiện - và luôn luôn là biểu thức
boolean.
- Trong thời gian chạy, biểu thức toán hạng bên trái được đánh giá đầu tiên; nếu kết quả có loại
Boolean, nó phải chịu chuyển đổi unboxing ( §5.1.8 ).
- Nếu giá trị kết quả là
false, giá trị của biểu thức có điều kiện và và biểu thức falsetoán hạng bên phải không được ước tính.
- Nếu giá trị của toán hạng bên trái là
true, thì biểu thức bên phải được ước tính; nếu kết quả có loại Boolean, nó phải chịu chuyển đổi unboxing ( §5.1.8 ). Giá trị kết quả trở thành giá trị của điều kiện-và biểu thức.
- Do đó,
&&tính kết quả tương tự như &trên booleantoán hạng. Nó chỉ khác ở chỗ biểu thức toán hạng bên phải được đánh giá có điều kiện chứ không phải luôn luôn.
Có điều kiện-Hoặc có các thuộc tính sau:
- Toán tử có điều kiện - hoặc toán tử là liên kết trái cú pháp (nhóm này từ trái sang phải).
- Toán tử có điều kiện hoặc hoàn toàn liên quan đến cả tác dụng phụ và giá trị kết quả. Đó là, đối với bất kỳ biểu thức
a, bvà c, đánh giá của biểu thức ((a) || (b)) || (c)tạo ra kết quả tương tự, với các tác dụng phụ tương tự xảy ra theo thứ tự, như đánh giá của biểu thức (a) || ((b) || (c)).
- Mỗi toán hạng của toán tử có điều kiện hoặc phải có kiểu
booleanhoặc hoặc Booleanxảy ra lỗi thời gian biên dịch.
- Kiểu của một điều kiện-hoặc biểu thức luôn luôn là
boolean .
- Trong thời gian chạy, biểu thức toán hạng bên trái được đánh giá đầu tiên; nếu kết quả có loại
Boolean, nó phải chịu chuyển đổi unboxing ( §5.1.8 ).
- Nếu giá trị kết quả là
true, giá trị của biểu thức có điều kiện làtrue và biểu thức toán hạng bên phải không được ước tính.
- Nếu giá trị của toán hạng bên trái là
false, thì biểu thức bên phải được ước tính; nếu kết quả có loại Boolean, nó phải chịu chuyển đổi unboxing ( §5.1.8 ). Giá trị kết quả trở thành giá trị của biểu thức có điều kiện-hoặc.
- Do đó,
||tính kết quả tương tự như |trên booleanhoặc Booleantoán hạng. Nó chỉ khác ở chỗ biểu thức toán hạng bên phải được đánh giá có điều kiện chứ không phải luôn luôn.
Nói tóm lại, như @JohnMeagher đã nhiều lần chỉ ra trong các bình luận, &và |trên thực tế, các toán tử boolean không ngắn mạch trong trường hợp cụ thể của toán hạng là booleanhoặc Boolean. Với các thực hành tốt (nghĩa là: không có tác dụng phụ), đây là một sự khác biệt nhỏ. Tuy nhiên, khi các toán hạng không phải booleanlà s hoặc Booleans, các toán tử hoạt động rất khác nhau: các phép toán bit và logic đơn giản là không so sánh tốt ở mức độ cao của lập trình Java.