เหตุใดคำสั่ง if ที่มีการมอบหมายงานและการตรวจสอบความเท่าเทียมจึงประเมินว่าเป็นเท็จ


105

คำสั่ง Java ifทำงานอย่างไรเมื่อมีการกำหนดและการตรวจสอบความเท่าเทียมORกัน?

public static void test() {
    boolean test1 = true; 
    if (test1 = false || test1 == false) {
        System.out.println("TRUE");
    } else {
        System.out.println("FALSE");
    }       
}

เหตุใดการพิมพ์นี้จึงเป็นเท็จ


1
เรียกใช้และตรวจสอบ ดูว่ามีการพิมพ์ค่าบูลีนอะไรหากคุณกำหนดเป็นเท็จและถ้าคุณกำหนดค่าจริง จากนั้นอ่านวิธีการทำงานของ OR
Pratik

2
ฉันอยากจะบอกว่ารหัสนี้ในโหมด debug ให้ค่า TRUE และในโหมด Running ให้ค่า FALSE ... ทำไมจึงเป็นเช่นนั้น ??? ... (ฉันใส่เบรกพอยต์ไว้ที่เงื่อนไข if) ...
CoderNeji

test1=false, test1==falseคือfalse, false || falseคือซึ่งเป็นfalse or false false
Jared Burrows

ฉันรู้ว่าคุณไม่ได้ขอคำแนะนำ แต่เนื่องจากคำตอบด้านล่างระบุปัญหาที่สำคัญกว่านี่คือแนวทางปฏิบัติสองสามข้อที่ช่วยให้ฉันหลีกเลี่ยงปัญหา (เมื่อฉันปฏิบัติตาม): (1) ใช้วงเล็บเสมอเมื่อไม่ 100% ความสำคัญบางประการหรือเพื่อความชัดเจนที่ง่ายขึ้นเพื่อช่วยเหลือนักพัฒนาซอฟต์แวร์รายอื่น อย่าคิดว่าผู้อื่นจะจำกฎลำดับความสำคัญสำหรับตัวดำเนินการทั้งหมด (2) โดยทั่วไปควรหลีกเลี่ยงการกำหนด if-assignment เพื่อลดความสับสนยกเว้น if-condition ที่ง่ายมาก มีข้อยกเว้นทั่วไปบางประการ (โดยเฉพาะอย่างยิ่งสำหรับการตรวจสอบ I / O ระบบเครือข่าย ฯลฯ ) แค่สองเซ็นต์ของฉัน
rimsky

เพราะว่าtest1 = true
jono

คำตอบ:


189

สำนวนไม่ได้แยกวิเคราะห์อย่างที่คุณคิด มันไม่ใช่

(test1=false) || (test1 == false)

ในกรณีนี้ผลลัพธ์จะเป็นtrueอย่างไร แต่

test1 = (false || test1 == false)

ค่าของfalse || test1 == falseนิพจน์จะคำนวณก่อนและเป็นfalseเพราะtest1ถูกตั้งค่าให้trueเข้าสู่การคำนวณ

เหตุผลที่จะแยกกันด้วยวิธีนี้คือการที่มีความสำคัญของ||ต่ำกว่า==ผู้ประกอบการ =แต่สูงกว่าความสำคัญของผู้ประกอบการที่ได้รับมอบหมาย


2
1 @RohanFernando โปรดทราบว่าถ้าคุณจะเพิ่มวงเล็บรอบ ๆ ที่ได้รับมอบหมายเช่นดังนั้น: มูลค่าโดยรวมจะ((test1 = false) || test1 == false) true
Arnon Zilca

1
โปรดเขียนเหตุผลที่การแยกวิเคราะห์เกิดขึ้น ... เป็นเพราะลำดับความสำคัญของตัวดำเนินการหรือไม่?
kondu

3
@kondu นั่นเป็นธรรมติดตามคำถามผมแก้ไขเพื่อเพิ่มการเชื่อมโยงไปยังตารางมีความสำคัญซึ่งแสดงให้เห็นว่า==อยู่เหนือ||แต่อยู่ด้านล่าง= ||
dasblinkenlight

ย่อหน้าสุดท้ายทำให้เข้าใจผิดในแง่ที่จะเข้าใจว่าเหตุใดการแยกวิเคราะห์ที่สองจึงถูกเลือกแทนที่จะเป็นแบบแรกก็พอที่จะทราบกฎ (ที่จำได้ง่าย) ว่าการมอบหมายมีความสำคัญต่ำกว่าตัวดำเนินการใด ๆ ที่ไม่ได้มอบหมาย (ที่นี่||) ความสำคัญของญาติ||และ==มีความเกี่ยวข้องเท่านั้นที่จะแสดงให้เห็นว่าการแยกเป็นไม่ได้ในขณะtest1 = ((false || test1) == false)ที่ฉันไม่คิดว่าใครสมควรจะคาดหวัง (โดยวิธีการที่ญาติมีความสำคัญหรือมากกว่าโดยทั่วไปว่า ||, &&มีความสำคัญต่ำกว่าความสัมพันธ์ยังเป็นเรื่องง่ายที่จะ จำไว้เนื่องจากใช้ตลอดเวลา)
Marc van Leeuwen

1
@MarcvanLeeuwen ลำดับญาติของ||และ==เทียบ||และ=อธิบายว่าทำไมพฤติกรรมนี้แตกต่างจาก (ธรรมดา) a == b || c == dกรณีของ
Aaron Dufour

83

นี่เป็นประเด็นสำคัญโดยพื้นฐานแล้ว คุณสมมติว่ารหัสของคุณเทียบเท่ากับ:

if ((test1 = false) || (test1 == false))

... แต่มันไม่ใช่ มันเทียบเท่ากับ:

if (test1 = (false || test1 == false))

... ซึ่งเทียบเท่ากับ:

if (test1 = (false || false))

(เพราะtest1เป็นtrueการเริ่มต้นด้วย)

... ซึ่งเทียบเท่ากับ:

if (test1 = false)

ซึ่งกำหนดค่าfalseจะมีผลของการเป็นการแสดงออกtest1false

ดูบทแนะนำ Java เกี่ยวกับตัวดำเนินการสำหรับตารางลำดับความสำคัญของตัวดำเนินการที่เป็นประโยชน์


2

โปรดดูลำดับความสำคัญของตัวดำเนินการ

นิพจน์test1 = false || test1 == falseจะประเมินตามขั้นตอนต่อไป

ขั้นตอน: 1- test1 = false || test1 == false // ลำดับความสำคัญ==สูงสุด

STEP: 2- test1 = false || false // Operator ||มีลำดับความสำคัญสูงกว่า

ขั้นตอน: 3- test1 = false

ขั้นตอน: 4- false

เนื่องจากค่าบูลีนของนิพจน์กลายเป็นเท็จคำสั่งอื่นจึงถูกดำเนินการ


-11

(test1 = false || test1 == false)ส่งคืนเท็จเนื่องจากทั้งสองเป็นเท็จ (test1 = false || test1 == true)นี่เป็นเรื่องจริงเพราะหนึ่งในนั้นเป็นความจริง


1
ผิดอย่างสิ้นเชิง เหตุใดคุณจึงตอบด้วยข้อมูลที่ไม่ถูกต้องเช่นนี้หลายวันหลังจากที่คำถามได้รับคำตอบคุณภาพสูงสองคำซึ่งอธิบายถึงสิ่งที่เกิดขึ้น
l4mpi

5
คำตอบสองคำที่มีคุณภาพต่ำเช่นนี้ไม่สมควรได้รับความคิดเห็นเป็นลายลักษณ์อักษรแยกกัน คุณตระหนักดีว่าคำตอบของคุณเป็นเรื่องไร้สาระใช่ไหม? ถ้าไม่อ่านคำตอบของ Jon และไฟกะพริบทั้งสองอย่างละเอียด
l4mpi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.