ทะลึ่ง
boolean a = false;
ฉันสงสัยว่าถ้าทำ:
a &= b;
เทียบเท่ากับ
a = a && b; //logical AND, a is false hence b is not evaluated.
หรือในทางกลับกันหมายความว่า
a = a & b; //Bitwise AND. Both a and b are evaluated.
ทะลึ่ง
boolean a = false;
ฉันสงสัยว่าถ้าทำ:
a &= b;
เทียบเท่ากับ
a = a && b; //logical AND, a is false hence b is not evaluated.
หรือในทางกลับกันหมายความว่า
a = a & b; //Bitwise AND. Both a and b are evaluated.
คำตอบ:
จากข้อมูลจำเพาะภาษาชวา - 15.26.2 ผู้ประกอบการกำหนด
นิพจน์การมอบหมายผสมของฟอร์ม
E1 op= E2
เทียบเท่ากับE1 = (T)((E1) op (E2))
โดยที่T
เป็นประเภทE1
ยกเว้นว่าE1
ถูกประเมินเพียงครั้งเดียว
ดังนั้นจะเทียบเท่ากับa &= b;
a = a & b;
(ในประเพณีบางอย่างการหล่อแบบนั้นสร้างความแตกต่างให้กับผลลัพธ์ แต่ในอันนี้b
ต้องเป็นboolean
และการหล่อแบบไม่ได้ทำอะไรเลย)
และสำหรับบันทึกa &&= b;
นั้นไม่ถูกต้อง Java ไม่มี&&=
ผู้ให้บริการ
ในทางปฏิบัติมีความแตกต่างความหมายเล็ก ๆ น้อย ๆ ระหว่างและa = a & b;
a = a && b;
(ถ้าb
เป็นตัวแปรหรือค่าคงที่ผลลัพธ์จะเหมือนกันสำหรับทั้งสองรุ่นมีความแตกต่างทางความหมายเมื่อb
มีนิพจน์ย่อยที่มีผลข้างเคียงเท่านั้นใน&
กรณีผลข้างเคียงจะเกิดขึ้นเสมอใน&&
กรณีมันเกิดขึ้นขึ้นอยู่กับมูลค่าของa
.)
ในด้านประสิทธิภาพการปิดอยู่ระหว่างค่าใช้จ่ายในการประเมินb
และค่าใช้จ่ายของการทดสอบและสาขาของค่าของและการประหยัดที่มีศักยภาพในการหลีกเลี่ยงงานที่ไม่จำเป็นเพื่อa
a
การวิเคราะห์ไม่ได้เป็นแบบตรงไปข้างหน้า แต่ถ้าค่าใช้จ่ายในการคำนวณb
นั้นไม่สำคัญความแตกต่างของประสิทธิภาพระหว่างสองเวอร์ชันนั้นเล็กเกินไปที่จะพิจารณาว่าคุ้มค่า
ดู15.22.2 ของ JLS สำหรับตัวถูกดำเนินการบูลีนโอเป&
อเรเตอร์คือบูลีนไม่ใช่ระดับบิต ความแตกต่างเพียงอย่างเดียวระหว่าง&&
และ&
สำหรับตัวถูกดำเนินการบูลีนก็คือว่า&&
มันเป็นวงจรสั้น (หมายความว่าตัวถูกดำเนินการที่สองไม่ได้รับการประเมินถ้าตัวถูกดำเนินการครั้งแรกประเมินเป็นเท็จ)
ดังนั้นในกรณีของคุณถ้าb
เป็นดั้งเดิมa = a && b
, a = a & b
และa &= b
ทุกคนทำในสิ่งเดียวกัน
เป็นคนสุดท้าย:
a = a & b;
นี่คือวิธีทดสอบง่ายๆ:
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
ดังนั้นตัวถูกดำเนินการทางขวาจะถูกประเมิน
ดังนั้นดังกล่าวแล้วโดยคนอื่น ๆ เป็นเช่นเดียวกับa &= b
a = a & b
ฉันเจอสถานการณ์ที่คล้ายกันโดยใช้บูลีนซึ่งฉันต้องการหลีกเลี่ยงการโทร b () ถ้า a เป็นเท็จอยู่แล้ว
สิ่งนี้ใช้ได้กับฉัน:
a &= a && b()
a=a&&b()
คุณก็สามารถเขียน