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 ShiftExpression
và ReferenceType
được xác định trong §15.19 và §4.3 , tương ứng. ShiftExpression
yê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ù ReferenceType
khô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 boolean
hoặ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 int
s 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à boolean
hoặ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 true
nếu cả hai toán hạng là true
, ^
sẽ dẫn đến true
nếu cả hai toán hạng khác nhau và|
sẽ dẫn đến true
nế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
, b
và 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
boolean
hoặc hoặc Boolean
xả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 false
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à
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 boolean
toá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
, b
và 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
boolean
hoặc hoặc Boolean
xả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 boolean
hoặc Boolean
toá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à boolean
hoặ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 boolean
là s hoặc Boolean
s, 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.