2012-09-23 18 views
25

Trong các trang như http://en.wikipedia.org/wiki/?: toán tử ba năm/điều kiện ?: dường như được sử dụng cho các bài tập có điều kiện. Tôi đã cố sử dụng nó để gọi phương thức, như sau:Toán tử ternary/có điều kiện (? :) của Java có thể được sử dụng để gọi các phương thức thay vì gán các giá trị không?

(condition) ? doThis() : doThat(); 

Cả hai phương thức đều bị hủy. Java nói với tôi nó không phải là một tuyên bố.

Vì vậy, tôi đoán tôi không thể thực hiện cuộc gọi phương thức có điều kiện ... hay tôi có thể?

+14

Không, không phải như vậy. Chỉ cần sử dụng 'if' như một người bình thường. –

+1

Tôi tin rằng toán tử bậc ba có nghĩa vụ gán giá trị cho một thể hiện của một loại, với một điều kiện kiểm tra. cách bạn đang đề xuất nó không thỏa mãn định dạng. –

+0

@codesparkle - không nhiều không gian. if (condition) {doThis();} else {doThat();} – tehdoommarine

Trả lời

18

Hãy nghĩ đến các toán tử bậc ba như một phương pháp trong trường hợp này. Nói a ? b : c là (đối với các tính năng bạn đang cân nhắc, xem bình luận lasseespeholt của) tương đương với cách gọi phương thức giả:

ternary(a, b, c) 
    if a 
     return b 
    else 
     return c 

đó là lý do tại sao mọi người có thể nói những câu như x = a ? b : c; về cơ bản giống như nói là x = ternary(a, b, c). Khi bạn nói (condition) ? doThis() : doThat(), bạn đang có hiệu lực nói:

if condition 
    return doThis() 
else 
    return doThat() 

Nhìn những gì sẽ xảy ra nếu chúng ta cố gắng thay thế các phương pháp cho những gì họ trở

if condition 
    return ??? 
else 
    return ??? 

Nó thậm chí không có ý nghĩa để xem xét nó . doThis()doThat() không trả về bất kỳ điều gì, vì void không phải là loại có thể tức thì, do đó phương thức ternary cũng không thể trả về bất kỳ điều gì, vì vậy Java không biết phải làm gì với tuyên bố của bạn và khiếu nại. Có một số cách giải quyết vấn đề này, nhưng chúng đều là thực hành không tốt (bạn có thể sửa đổi các phương thức để có giá trị trả về nhưng không làm gì với những gì chúng trả về, bạn có thể tạo các phương thức mới gọi phương thức của bạn và sau đó trả về null, v.v.) Bạn tốt hơn rất nhiều chỉ bằng cách sử dụng một tuyên bố if trong trường hợp này.

EDIT Ngoài ra, còn có một vấn đề lớn hơn nữa. Ngay cả khi bạn đã trả về các giá trị, Java không xem xét một tuyên bố theo bất kỳ ý nghĩa nào.

+1

" Nói a? b: c tương đương với việc gọi phương thức giả mã "<- Không. Hãy xem xét tình huống mà 'b' hoặc' c' có tác dụng phụ. Vì vậy, bạn cần phải xem xét những người như lambdas như bạn làm trong ví dụ sau này của bạn. –

+0

Đúng. Tôi sẽ làm rõ rằng tôi đang đơn giản hóa. – Jodaka

+3

@Jodaka, tôi coi bản chỉnh sửa của bạn là câu trả lời đúng bởi vì nó không thực sự về việc trả về một giá trị, đó là về Java không xem xét một? b: c như một tuyên bố. – Kareem

2

Toán tử bậc ba chỉ đơn giản là đường cú pháp.
Làm cho mã dễ đọc/ghi hơn nhưng không thêm chức năng thực.
Việc sử dụng chính của nó là nén nhiều dòng mã thành một dòng và rất hữu ích khi xây dựng các chuỗi chỉ khác một chút, dựa trên một số điều kiện.

ví dụ:

Collection<?> col = ... 
System.out.println("There " + (col.size()==1 ? "is" : "are") + " " 
    + col.size() + " " + (col.size()==1 ? "element" : "elements") 
    + " in the collection"); 

thay vì

Collection<?> col = ... 
String message = "There "; 
if(col.size()==1) 
    message += "is"; 
else 
    message += "are"; 
message += " "+col.size() 
if(col.size()==1) 
    message += " element"; 
else 
    message += " elements"; 
message += " in the collection"; 
System.out.println(message); 

Như bạn có thể thấy, nó đơn giản hoá mã.
(lưu ý: Trong ví dụ thứ hai nó là tốt hơn để sử dụng StringBuilder thay vì String nối)

Nhưng kể từ (condition) ? doThis() : doThat(); (không có giá trị trả về) đã cùng ý nghĩa như if(condition) doThis(); else doThat(); sẽ có hai cách để viết những điều tương tự, mà không thêm chức năng.Nó sẽ chỉ làm phức tạp mọi thứ:

  • cho các lập trình viên: Mã không đồng đều
  • cho việc thực hiện các nhà điều hành ternary: bây giờ nó phải cũng hỗ trợ void phương pháp

Vì vậy Không, không thể sử dụng thao tác bậc ba để gọi phương thức có điều kiện. Sử dụng if-else thay thế:

if(condition) 
    doThis(); 
else 
    doThat(); 
1

Toán tử ba năm (điều kiện) trả về một giá trị. Nếu các phương thức của bạn không, chúng không thể được sử dụng như một phần của toán tử (nơi nó lấy giá trị).

Để hiểu rõ hơn, hãy nghĩ về một toán tử nhị phân đơn giản: +. Nó hoạt động theo cách này:

<eval1> + <eval2> --> <value> 

Cần 2 phần có giá trị và trả về một phần khác. Nếu bạn đã gõ

doThis() + doThat(); 

hoặc thậm chí

gimmeAValue = doThis() + doThat(); 

nó sẽ thất bại, như không doThis() cũng không doThat() đánh giá bất cứ điều gì (họ "trở lại" void). Tất nhiên, cả hai <eval1><eval2> phải thuộc một số loại "tương thích" để nhà điều hành + có thể xử lý chúng và trả lại giá trị của một số loại.

Bây giờ chúng ta hãy xem các nhà điều hành ternary:

<evalBoolean> ? <eval1> : <eval2> --> <value> 

Phải mất 3 có thể đánh giá phần, và trả về một giá trị.

Phần đánh giá đầu tiên phải dễ hiểu (có thể truyền) bởi trình biên dịch dưới dạng boolean. Nó sẽ được sử dụng để quyết định phần nào trong số 2 phần còn lại phải được trả về.

Hai phần còn lại có giá trị khác phải, cũng ... có giá trị. Một cái gì đó. Của một số loại.

Nói cách khác: toán tử điều kiện bậc ba có ý định trả về một cái gì đó, không phải là phân nhánh mã. Được sử dụng theo cách này:

gimmeAValue = testMe() ? returnThis() : returnThat();