Câu trả lời:
Đó là các toán tử bitwise AND và bitwise OR.
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
Cảm ơn Carlos đã chỉ ra phần thích hợp trong Thông số ngôn ngữ Java ( 15.22.1 , 15.22.2 ) liên quan đến các hành vi khác nhau của toán tử dựa trên đầu vào của nó.
Thật vậy, khi cả hai đầu vào là boolean, các toán tử được coi là Toán tử logic Boolean và hoạt động tương tự như các toán tử Điều kiện-Và ( &&
) và Điều kiện-Hoặc ( ||
) ngoại trừ thực tế là chúng không ngắn mạch nên trong khi các toán tử sau là an toàn :
if((a != null) && (a.something == 3)){
}
Đây không phải là:
if((a != null) & (a.something == 3)){
}
"Đoản mạch" có nghĩa là người vận hành không nhất thiết phải kiểm tra tất cả các điều kiện. Trong các ví dụ trên, &&
sẽ chỉ kiểm tra điều kiện thứ hai khi a
không null
(nếu không thì toàn bộ câu lệnh sẽ trả về false và dù sao thì cũng sẽ rất khó để kiểm tra các điều kiện sau), do đó, câu lệnh của a.something
sẽ không đưa ra ngoại lệ hoặc được coi là "an toàn . "
Các &
nhà điều hành luôn kiểm tra mọi điều kiện trong mệnh đề, vì vậy trong các ví dụ trên, a.something
có thể được đánh giá khi a
thực chất là một null
giá trị, nâng cao một ngoại lệ.
Tôi nghĩ bạn đang nói về ý nghĩa hợp lý của cả hai toán tử, ở đây bạn có một sơ yếu lý lịch:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
Đánh giá ngắn mạch , đánh giá tối thiểu hoặc đánh giá McCarthy (sau John McCarthy) là ngữ nghĩa của một số toán tử Boolean trong một số ngôn ngữ lập trình trong đó đối số thứ hai chỉ được thực thi hoặc đánh giá nếu đối số đầu tiên không đủ để xác định giá trị của biểu thức: khi đối số đầu tiên của hàm AND cho giá trị false, giá trị tổng thể phải là false; và khi đối số đầu tiên của hàm OR được đánh giá là true, giá trị tổng thể phải là true.
Không an toàn có nghĩa là toán tử luôn kiểm tra mọi điều kiện trong mệnh đề, vì vậy trong các ví dụ trên, 1 / x có thể được đánh giá khi x thực tế là giá trị 0, tạo ra một ngoại lệ.
Tôi biết có rất nhiều câu trả lời ở đây, nhưng tất cả đều có vẻ hơi khó hiểu. Vì vậy, sau khi thực hiện một số nghiên cứu từ hướng dẫn học Java oracle, tôi đã đưa ra ba tình huống khác nhau về thời điểm sử dụng && hoặc &. Ba trường hợp là logic AND , bitwise AND và boolean AND .
Logical AND:
Logic AND (hay còn gọi là AND có điều kiện) sử dụng toán tử && . Nó có nghĩa là ngắn mạch: nếu toán hạng bên trái là sai, thì toán hạng bên phải sẽ không được đánh giá.
Thí dụ:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
Trong ví dụ trên, giá trị được in ra bảng điều khiển của x sẽ là 0, vì toán hạng đầu tiên trong câu lệnh if là sai, do đó java không cần tính toán (1 == ++ x) do đó x sẽ không được tính.
Bitwise AND: Bitwise AND sử dụng toán tử & . Nó được sử dụng để định dạng trước một hoạt động bitwise trên giá trị. Sẽ dễ dàng hơn nhiều để xem những gì đang xảy ra bằng cách xem hoạt động trên các số nhị phân, ví dụ:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
Như bạn có thể thấy trong ví dụ, khi các biểu diễn nhị phân của số 5 và 12 được xếp thẳng hàng, sau đó AND được định dạng sẵn một chút sẽ chỉ tạo ra một số nhị phân trong đó cùng một chữ số trong cả hai số có 1. Do đó 0101 & 1100 == 0100. Trong số thập phân là 5 & 12 == 4.
Boolean AND: Bây giờ toán tử boolean AND hoạt động tương tự và khác với cả AND bit và AND logic. Tôi thích nghĩ về nó như là định dạng trước một chút AND giữa hai giá trị boolean (hoặc các bit), do đó nó sử dụng toán tử & . Các giá trị boolean cũng có thể là kết quả của một biểu thức logic.
Nó trả về một giá trị đúng hoặc sai, giống như AND logic, nhưng không giống AND logic, nó không bị đoản mạch. Lý do là để nó định dạng trước AND bitwise đó, nó phải biết giá trị của cả toán hạng trái và phải. Đây là một người yêu cũ:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
Bây giờ khi câu lệnh if đó được chạy, biểu thức (1 == ++ x) sẽ được thực thi, ngay cả khi toán hạng bên trái là false. Do đó, giá trị được in ra cho x sẽ là 1 vì nó tăng dần.
Điều này cũng áp dụng cho Logical OR (||), bitwise OR (|), và boolean OR (|) Hy vọng điều này sẽ giải tỏa một số nhầm lẫn.
to preform that bitwise AND, it must know the value of both left and right operands
Điều này nghe có vẻ không đúng với tôi. Để thực hiện một BITWISE AND
toán hạng, bạn không cần phải biết toán hạng bên phải để có thể tìm ra kết quả nếu toán hạng bên trái là FALSE
. Những gì bạn giải thích là đúng, nhưng lý do bạn nhà nước dường như không phải như vậy, với tôi ít nhất ..
Các toán tử && và || bị đoản mạch, nghĩa là họ sẽ không đánh giá biểu thức bên phải của mình nếu giá trị của biểu thức bên trái đủ để xác định kết quả.
& và | cung cấp kết quả tương tự như && và || các toán tử. Sự khác biệt là chúng luôn đánh giá cả hai mặt của biểu thức trong đó là && và || ngừng đánh giá nếu điều kiện đầu tiên đủ để xác định kết quả.
&&
nó đánh giá cả hai kết quả trong khi ||
chỉ trả về nếu điều kiện đầu tiên là đúng.
( 2 & 4 )
đánh giá đến false
, trong khi ( 2 && 4 )
đánh giá với true
. Chính xác thì đó là kết quả như thế nào?
2 & 4
kết quả là một số nguyên, không phải là một boolean (0 trong trường hợp này). 2 && 4
sẽ không biên dịch, && chỉ chấp nhận boolean. Java không cho phép trộn các phép toán luận và ints: zero không phải là false
, false
không phải là không ...
&&
nó chỉ đánh giá toán hạng thứ hai nếu toán hạng đầu tiên là true
.
Trong Java, các toán tử đơn &, |, ^,! phụ thuộc vào các toán hạng. Nếu cả hai toán hạng đều là int, thì một phép toán bit sẽ được thực hiện. Nếu cả hai đều là boolean, một phép toán "logic" được thực hiện.
Nếu cả hai toán hạng không khớp, lỗi thời gian biên dịch sẽ được đưa ra.
Các toán tử kép &&, || hoạt động tương tự với các đối số đơn lẻ của chúng, nhưng cả hai toán hạng phải là biểu thức điều kiện, ví dụ:
if ((a <0) && (b <0)) {...} hoặc tương tự, if ((a <0) || (b <0)) {...}
nguồn: lập trình java lang 4th ed
&
và |
là toán tử bitwise trên các kiểu tích phân (ví dụ int
): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
và chỉ ||
hoạt động trên boolean (và đoản mạch, như các câu trả lời khác đã nói).
&
và |
cũng là toán tử boolean trên các kiểu boolean.
Có thể hữu ích khi biết rằng toán tử bitwise AND và bitwise OR luôn được đánh giá trước AND có điều kiện và OR có điều kiện được sử dụng trong cùng một biểu thức.
if ( (1>2) && (2>1) | true) // false!
&&; || là toán tử logic .... ngắn mạch
Nh & agrave; | là các toán tử logic boolean .... Không ngắn mạch
Chuyển đến sự khác biệt trong thực thi trên các biểu thức. Các toán tử bitwise đánh giá cả hai bên bất kể kết quả của phía bên trái. Nhưng trong trường hợp đánh giá biểu thức bằng các toán tử logic, việc đánh giá biểu thức bên phải phụ thuộc vào điều kiện bên trái.
Ví dụ:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Điều này sẽ in ra i = 26; j = 25, Vì điều kiện đầu tiên là sai, điều kiện bên phải bị bỏ qua vì kết quả là sai bất kể điều kiện bên phải. (ngắn mạch)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
Nhưng, điều này sẽ in ra i = 26; j = 26,
Nếu một biểu thức liên quan đến toán tử Boolean & được đánh giá, cả hai toán hạng đều được đánh giá. Sau đó, toán tử & được áp dụng cho toán hạng.
Khi một biểu thức liên quan đến toán tử && được đánh giá, toán hạng đầu tiên được đánh giá. Nếu toán hạng đầu tiên đánh giá là false, thì việc đánh giá toán hạng thứ hai sẽ bị bỏ qua.
Nếu toán hạng đầu tiên trả về giá trị true thì toán hạng thứ hai được đánh giá. Nếu toán hạng thứ hai trả về giá trị true thì toán tử && sẽ được áp dụng cho toán hạng thứ nhất và thứ hai.
Tương tự cho | và ||.
Trong khi sự khác biệt cơ bản là &
được sử dụng cho các hoạt động Bitwise chủ yếu trên long
, int
hoặc byte
nơi nó có thể được sử dụng cho loại mặt nạ, kết quả có thể khác nhau ngay cả khi bạn sử dụng nó thay vì logic &&
.
Sự khác biệt đáng chú ý hơn trong một số trường hợp:
Điểm đầu tiên là khá đơn giản, nó không gây ra lỗi, nhưng mất nhiều thời gian hơn. Nếu bạn có nhiều lần kiểm tra khác nhau trong một câu lệnh điều kiện, hãy đặt những phiếu kiểm tra rẻ hơn hoặc có nhiều khả năng bị lỗi hơn ở bên trái.
Đối với điểm thứ hai, hãy xem ví dụ này:
if ((a != null) & (a.isEmpty()))
Điều này không thành công null
vì đánh giá biểu thức thứ hai tạo ra a NullPointerException
. Toán tử logic &&
là lười biếng, nếu toán hạng bên trái là sai, kết quả là sai bất kể toán hạng bên phải là gì.
Ví dụ cho điểm thứ ba - giả sử chúng ta có một ứng dụng sử dụng DB mà không có bất kỳ trình kích hoạt hoặc tầng nào. Trước khi xóa đối tượng Tòa nhà, chúng ta phải thay đổi tòa nhà của đối tượng Bộ thành một đối tượng khác. Cũng giả sử trạng thái hoạt động được trả về dưới dạng boolean (true = thành công). Sau đó:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
Điều này đánh giá cả hai biểu thức và do đó thực hiện xóa tòa nhà ngay cả khi cập nhật bộ phận không thành công vì một số lý do. Với &&
, nó hoạt động như dự định và nó dừng lại sau lần thất bại đầu tiên.
Đối với a || b
, nó tương đương với !(!a && !b)
, nó dừng lại nếu a
đúng, không cần giải thích thêm.