Tại sao câu lệnh if này, với một phép gán và kiểm tra bình đẳng, lại đánh giá là false?


105

Câu lệnh if trong Java hoạt động như thế nào khi nó có một phép gán và một dấu kiểm bằng OR-d cùng nhau ??

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

Tại sao việc in này là SAI?


1
Chạy và kiểm tra. Xem giá trị boolean nào được in nếu bạn gán false và nếu bạn gán true. Sau đó, đọc về cách OR hoạt động.
Pratik

2
Tôi muốn nói rằng mã này ở chế độ gỡ lỗi cho giá trị TRUE và trên chế độ Chạy cho giá trị FALSE ... Tại sao lại như vậy ??? ... (Tôi đặt điểm ngắt của mình ở điều kiện if) ...
CoderNeji

test1=false, test1==falsefalse, false || falsefalse or falseđó là false.
Jared Burrows

Tôi biết bạn không hỏi ý kiến, nhưng khi các câu trả lời bên dưới xác định vấn đề ưu tiên, đây là một số phương pháp đã giúp tôi tránh gặp rắc rối (khi tôi tuân theo những điều này): (1) luôn sử dụng dấu ngoặc đơn khi không phải 100%. được ưu tiên nhất định hoặc để dễ đọc hơn để giúp các nhà phát triển khác. Đừng cho rằng những người khác sẽ nhớ các quy tắc ưu tiên cho tất cả các toán tử (2) các phép gán if thường nên tránh để giảm sự nhầm lẫn ngoại trừ các điều kiện if rất đơn giản. Có một số ngoại lệ phổ biến (đặc biệt là với các kiểm tra I / O đơn giản, mạng, v.v.). Chỉ hai xu của tôi.
rimsky

bởi vìtest1 = true
jono

Câu trả lời:


189

Biểu thức không được phân tích cú pháp theo cách bạn nghĩ. Nó không thể

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

trong trường hợp đó, kết quả sẽ là true, nhưng

test1 = (false || test1 == false)

Giá trị của false || test1 == falsebiểu thức được tính toán đầu tiên, và giá trị đó false, bởi vì test1nó được thiết lập để trueđi vào tính toán.

Lý do nó được phân tích cú pháp theo cách này là mức độ ưu tiên của toán tử ||thấp hơn của ==toán tử, nhưng cao hơn mức ưu tiên của toán tử gán =.


2
+1 @RohanFernando, cũng xin lưu ý rằng nếu bạn thêm dấu ngoặc quanh bài tập như vậy: ((test1 = false) || test1 == false)giá trị tổng thể sẽ là true.
Arnon Zilca

1
Hãy viết lý do tại sao phân tích cú pháp xảy ra như vậy ... Có phải do thứ tự ưu tiên của các toán tử?
kondu

3
@kondu Đó là một câu hỏi tiếp theo khá công bằng, tôi đã chỉnh sửa để thêm liên kết vào bảng ưu tiên, bảng này hiển thị ==ở trên ||, nhưng =ở dưới ||.
dasblinkenlight

Đoạn cuối cùng gây hiểu lầm, theo nghĩa là để hiểu tại sao phân tích cú pháp thứ hai được chọn thay vì phân tích cú pháp đầu tiên, nó đủ để biết quy tắc (dễ nhớ) rằng phép gán có quyền ưu tiên thấp hơn bất kỳ toán tử không gán nào (ở đây ||). Mức độ ưu tiên tương đối của ||==chỉ có liên quan để cho thấy rằng phân tích cú pháp không như trong test1 = ((false || test1) == false)đó, điều mà tôi không nghĩ rằng bất kỳ ai cũng mong đợi một cách hợp lý (bằng cách đó, mức độ ưu tiên tương đối, hoặc nói chung là ||, &&có mức độ ưu tiên thấp hơn so với quan hệ, cũng dễ dàng hãy nhớ, vì được sử dụng mọi lúc).
Marc van Leeuwen

1
@MarcvanLeeuwen Mức độ ưu tiên tương đối của ||==vs ||=giải thích tại sao điều này hoạt động khác với trường hợp (phổ biến) của a == b || c == d.
Aaron Dufour

83

Về cơ bản, đây là một vấn đề ưu tiên. Bạn đang giả định rằng mã của bạn tương đương với:

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

... nhưng không phải. Nó thực sự tương đương với:

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

... tương đương với:

if (test1 = (false || false))

(bởi vì test1trueđể bắt đầu với)

... tương đương với:

if (test1 = false)

đó gán giá trị falseđến test1, với kết quả của biểu thức con người false.

Xem hướng dẫn Java về toán tử để có bảng ưu tiên toán tử hữu ích.


2

vui lòng xem xét ưu tiên của các toán tử

Biểu thức test1 = false || test1 == falsesẽ đánh giá ở bước sau.

BƯỚC: 1- test1 = false || test1 == false // mức độ ưu tiên ==là cao nhất

BƯỚC: 2- test1 = false || false // Toán tử ||được ưu tiên cao hơn

BƯỚC 3- test1 = false

BƯỚC 4- false

Vì giá trị boolean của biểu thức trở thành sai nên câu lệnh else đang được thực thi.


-11

(test1 = false || test1 == false)trả về false, vì cả hai đều sai. (test1 = false || test1 == true)điều này đúng bởi vì một trong số chúng là đúng


1
Hoàn toàn sai. Tại sao bạn lại trả lời với thông tin không chính xác như vậy vài ngày sau khi câu hỏi nhận được hai câu trả lời chất lượng cao mô tả điều gì sẽ xảy ra?
l4mpi

5
Hai câu trả lời có chất lượng thấp như vậy không xứng đáng nhận xét bằng văn bản riêng lẻ. Bạn có nhận ra câu trả lời của bạn là vô nghĩa, phải không? Nếu không, hãy đọc kỹ hai câu trả lời của Jon và đèn nháy.
l4mpi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.