2012-09-23 12 views
25

Na stronach takich jak http://en.wikipedia.org/wiki/?: wydaje się, że potrójny/warunkowy operator ?: jest używany do przypisań warunkowych. Próbowałem użyć go do sposobu powołania, jak to:Czy potrójny/warunkowy operator Java (? :) może być używany do wywoływania metod zamiast przypisywania wartości?

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

Obie metody powrotu nieważne. Java mówi mi, że to nie jest oświadczenie.

Zgaduję, że nie mogę wykonywać warunkowych połączeń telefonicznych ... czy mogę?

+14

Nie, nie tak. Po prostu użyj 'if' jak normalna osoba. –

+1

Wierzę, że operator trójdzielny ma przypisać wartości do instancji typu, przy sprawdzaniu warunku. sposób, w jaki sugerujesz, że jest, nie jest zadowalający format. –

+0

@codesparkle - mało miejsca. if (warunek) {doThis();} else {doThat();} – tehdoommarine

Odpowiedz

18

Pomyśl o operatorach trójskładnikowych, takich jak metoda w tym przypadku. Mówiąc a ? b : c jest (dla zamiarów i celów bierzesz pod uwagę, patrz komentarz lasseespeholt za) równoważne wywołaniu metody pseudokod:

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

dlatego ludzie mogą mówić takie rzeczy jak x = a ? b : c; jest to po prostu jak powiedzenie x = ternary(a, b, c). Kiedy mówisz (condition) ? doThis() : doThat(), jesteś w rzeczywistości, mówiąc:

if condition 
    return doThis() 
else 
    return doThat() 

Spójrz co się dzieje, jeśli staramy się zastąpić metody co wrócą

if condition 
    return ??? 
else 
    return ??? 

To nie ma sensu, aby go rozważyć . doThis() i doThat() nic nie zwracają, ponieważ void nie jest typem natychmiastowym, więc metoda ternary również nie może niczego zwrócić, więc Java nie wie, co zrobić z oświadczeniem i skargami.

Jest wiele sposobów na obejście tego problemu, ale wszystkie są złymi praktykami (można zmodyfikować metody, aby uzyskać wartość zwracaną, ale nie robić nic z tym, co zwracają, można tworzyć nowe metody wywołujące metody, a następnie return null, itp.). Znacznie lepiej jest po prostu użyć instrukcji if w tym przypadku.

EDIT Co więcej, jest jeszcze większy problem. Nawet jeśli zwracałeś wartości, Java nie traktuje w żadnym sensie stwierdzenia w postaci a ? b : c.

+1

" Powiedzenie? b: c jest równoważne wywołaniu metody pseudokodowej "<- Nie. Rozważ sytuację, w której 'b' lub' c' ma efekty uboczne. Musisz więc traktować je jak lambdy, tak jak to robisz w późniejszych przykładach. –

+0

Prawda. Wyjaśnię, że upraszczam. – Jodaka

+3

@Jodaka, uważam, że twoja edycja jest poprawną odpowiedzią, ponieważ tak naprawdę nie chodzi o zwrócenie wartości, ponieważ Java nie bierze pod uwagę? b: c jako oświadczenie. – Kareem

2

Operator potrójny to po prostu cukier syntaktyczny.
Ułatwia to odczyt i zapis kodu, ale nie dodaje rzeczywistej funkcjonalności.
Jego głównym zastosowaniem było skompresowanie kilku linii kodu do pojedynczej linii i było bardzo użyteczne podczas budowania ciągów, które różnią się tylko nieznacznie, w zależności od pewnych warunków.

np.

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

zamiast

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); 

Jak widać, to upraszcza kod.
(Uwaga: W drugim przykładzie lepiej jest użyć StringBuilder zamiast konkatenacji String)

Ale ponieważ (condition) ? doThis() : doThat(); (bez wartości zwracanych) ma takie samo znaczenie jak if(condition) doThis(); else doThat(); nie byłoby dwa sposoby pisania samo, bez dodanie funkcjonalności.Byłoby to tylko skomplikować rzeczy:

  • dla programistów: kod nie jest jednolita
  • dla realizacji operatora potrójnego: ma teraz również wsparcia void metody

Więc No, operacja trójskładnikowa nie może być używana do warunkowego wywoływania metod. Użyj, jeśli zamiast tego:

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

Operator trójskładnikowy zwraca wartość. Jeśli twoje metody nie są, nie mogą być używane jako części operatora (gdzie ma wartość).

Aby lepiej to zrozumieć, pomyślmy o jednym prostym operatorze binarnym: +. Działa to w ten sposób:

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

Wymaga 2 podlegających ocenie części i zwraca drugą. Jeśli wpisałeś

doThis() + doThat(); 

lub nawet

gimmeAValue = doThis() + doThat(); 

to nie uda, ponieważ ani doThis() ani doThat() ocenić do niczego (są "powrót" void). Oczywiście zarówno <eval1>, jak i <eval2> muszą być typu "kompatybilnego", aby operator + mógł sobie z nimi poradzić i zwrócić wartość pewnego rodzaju.

Teraz zobaczmy operator potrójny:

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

To trwa 3 ocenianych części i zwraca wartość.

Pierwsza możliwa do oceny część musi być zrozumiała (odlewna) przez kompilator jako boolean. Zostanie on użyty do podjęcia decyzji, która z dwóch podlegających ocenie części ma zostać zwrócona.

Pozostałe dwie podlegające ocenie części muszą być dobrze ... do oceny. Do czegoś. Z pewnego rodzaju.

Innymi słowy: trójargumentowy operator warunkowy ma zwrócić coś, a nie rozgałęzienie kodu. Używane w ten sposób:

gimmeAValue = testMe() ? returnThis() : returnThat(); 
Powiązane problemy