2010-02-15 37 views
46

Hãy lấy một ví dụ đơn giản về một đối tượng Cat. Tôi muốn chắc chắn rằng "không rỗng" cat có màu cam hoặc xám.Trong Java, "thứ tự hoạt động" boolean là gì?

if(cat != null && cat.getColor() == "orange" || cat.getColor() == "grey") { 
//do stuff 
} 

Tôi tin và đến trước, sau đó là OR. Mặc dù tôi hơi mờ, vì vậy đây là các câu hỏi của tôi:

  1. Ai đó có thể hướng dẫn tôi thông qua tuyên bố này vì vậy tôi chắc chắn rằng tôi sẽ làm gì?

  2. Ngoài ra, điều gì sẽ xảy ra nếu tôi thêm dấu ngoặc đơn; điều đó có thay đổi thứ tự hoạt động không?

  3. Thứ tự hoạt động của tôi có thay đổi từ ngôn ngữ này sang ngôn ngữ khác không?

+11

Nếu bạn bối rối, hãy thêm dấu ngoặc đơn để hiển thị. –

+34

Thậm chí nếu nó không mờ với bạn, hãy thêm dấu ngoặc đơn để người khác cũng có thể hiểu được. –

+2

Từ wikipedia trên logic boolean: Trong những trường hợp như vậy [của sự mơ hồ], dấu ngoặc đơn có thể được sử dụng để làm rõ thứ tự các hoạt động. Như mọi khi, các hoạt động bên trong cặp trong cùng được thực hiện trước tiên, tiếp theo là cặp tiếp theo, vv, cho đến khi tất cả các hoạt động trong ngoặc đơn đã được hoàn thành. Sau đó, bất kỳ hoạt động nào bên ngoài dấu ngoặc đơn được thực hiện. – Stephano

Trả lời

54

Hướng dẫn Java có danh sách minh họa operator precedence. Các toán tử bình đẳng sẽ được đánh giá trước, sau đó &&, sau đó ||. Dấu ngoặc đơn sẽ được đánh giá trước bất kỳ thứ gì khác, vì vậy việc thêm chúng có thể thay đổi thứ tự. Điều này thường khá giống nhau từ ngôn ngữ này sang ngôn ngữ khác, nhưng bạn nên kiểm tra kỹ. Đây là một biến thể nhỏ trong hành vi mà bạn không mong đợi có thể khiến bạn mất cả ngày để gỡ lỗi, vì vậy bạn nên đặt các dấu ngoặc đơn vào vị trí để chắc chắn thứ tự đánh giá sẽ là gì .

+1

@VinceEmigh Các toán hạng không cần phải được đánh giá theo thứ tự như ưu tiên của toán tử. Thậm chí nếu bạn thêm dấu ngoặc đơn, chương trình vẫn có thể thấy rằng 'if (true || (true && s.equals (" ")))' sẽ luôn luôn là 'true', vì vậy nó không cần đánh giá' s.equals ("") '. –

+0

Tệ của tôi, tôi mới nhận ra mình bị nhầm lẫn nặng nề. Tôi đã không nghĩ về quyền ưu tiên một cách chính xác. Tôi đã suy nghĩ về mặt đánh giá (được đánh giá đầu tiên), như trong đó nhà điều hành "sở hữu" các booleans –

14

trật tự Boolean hoạt động (trong tất cả các ngôn ngữ tôi tin rằng):

  1. Parens
  2. KHÔNG
  3. HOẶC

Vì vậy, logic của bạn trên là tương đương đến:

(cat != null && cat.getColor() == "orange") || cat.getColor() == "grey" 
4

Đầu tiên, bạn câu lệnh if chứa ba biểu thức chính:

  1. mèo = null
  2. cat.getColor() == "màu da cam"
  3. cat.getColor() == "màu xám! "

Biểu thức đầu tiên chỉ đơn giản là kiểm tra xem con mèo có rỗng không. Nếu cần thiết thì biểu thức thứ hai sẽ được thực thi và kết quả là NPE(null pointer excpetion). Đó là lý do tại sao việc sử dụng & & giữa biểu thức đầu tiên và thứ hai. Khi bạn sử dụng &&, nếu biểu thức đầu tiên đánh giá sai thì biểu thức thứ hai sẽ không bao giờ được thực hiện. Cuối cùng, bạn kiểm tra xem màu của mèo có màu xám hay không.

Cuối cùng lưu ý rằng nếu tuyên bố là vẫn sai vì nếu mèo là null, biểu thức thứ ba vẫn là thực hiện và do đó bạn sẽ có được một rỗng con trỏ ngoại lệ.

Cách đúng để làm việc đó là:

if(cat != null && (cat.getColor() == "orange" || cat.getColor() == "grey")) { 
//do stuff 
} 

Kiểm tra trình tự ngoặc.

8

Khái niệm về cơ bản là giống hệt nhau để:

if ((cat != null && cat.getColor() == "orange") || cat.getColor() == "grey") { 
    ... 
} 

Các thứ tự ưu tiên ở đây là AND (&&) có độ ưu tiên cao hơn OR (||).

Bạn cũng nên biết rằng việc sử dụng == để kiểm tra tính bình đẳng chuỗi sẽ đôi khi hoạt động trong Java nhưng không phải cách bạn nên thực hiện. Bạn nên làm:

if (cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) { 
    ... 
} 

tức là sử dụng các phương pháp equals() cho String so sánh, không == mà chỉ đơn giản thực hiện bình đẳng tham khảo. Tham chiếu bình đẳng cho các chuỗi có thể gây hiểu nhầm. Ví dụ:

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a == b); // false 
+0

Tôi nghĩ bạn đang thiếu một ví dụ trong ví dụ đầu tiên, hoặc tôi quá mệt mỏi. –

+0

@ Robert: chúng đã bị rối tung lên. Cố định, cảm ơn. – cletus

3

Vâng && chắc chắn được đánh giá trước ||. Nhưng tôi thấy bạn đang làm cat.getColor() == "orange" mà có thể cho bạn kết quả không mong muốn. Thay vào đó, bạn có thể muốn thay thế:

if(cat != null && ("orange".equals(cat.getColor()) || "grey".equals(cat.getColor()))) { 
    //do stuff 
} 
-2

Thứ tự hoạt động không phải là những gì bạn cần, bạn cần đại số boolean, bao gồm các hàm boolean. Maxterms/minterms, mã màu xám, bảng Karnaugh, điốt, bóng bán dẫn, cổng logic, bộ ghép kênh, bitadders, flip flops ... Điều bạn muốn là thực hiện logic "logic" trên máy tính hoặc máy ảo. Với "thứ tự hoạt động", bạn có thể giới thiệu một cái gì đó về vật lý như quản lý sự chậm trễ trên các cổng logic (HOẶC, nếu) khoảng nano giây?

Các vấn đề liên quan