Słyszałem od kogoś, że null == object
jest to lepsze niż object == null
sprawdzanie
np .:
void m1(Object obj ) {
if(null == obj) // Is this better than object == null ? Why ?
return ;
// Else blah blah
}
Czy są jakieś powody, czy to kolejny mit? Dzięki za pomoc.
null
odniesień domyślnym sposobem działania powinno być wyrzucenie NPE. Niektóre fajne biblioteki (takie jak biblioteka JDK7 Java) mają metodę podobną dopublic static <T> T notNull(T obj) { if (obj == null) { throw new NullPointerException(); } else { return obj; } }
. Jest też@NonNull
(lub@Nonnull
?), Ale to zostaje „wymazane”.null == object
jest znany jako stan Yody .Odpowiedzi:
Jest to prawdopodobnie nawyk wyuczony od C, aby uniknąć tego rodzaju literówki (pojedyncza
=
zamiast podwójna==
):Konwencja umieszczania stałej po lewej stronie
==
nie jest tak naprawdę przydatna w Javie, ponieważ Java wymaga, aby wyrażenie wif
ewaluacji miałoboolean
wartość, więc jeśli stała to aboolean
, wystąpiłby błąd kompilacji w każdym przypadku argumenty. (a jeśli jest to wartość logiczna, i tak nie powinieneś jej używać==
...)źródło
x.booleanValue()
lub!x.booleanValue()
.x == true
lubx == false
w wyrażeniu warunkowym to nieprzyjemny zapach, IMHO.null == object
tylko w celu upewnienia się, że nie nadpisujemy obiektu przypadkowo literówką, nie powinno w ogóle być przypadkiem użycia. Co oznacza, że uczymy się, że teraz, gdy najpierw używam „null”, jest w porządku, nawet jeśli popełnię błąd. Nie oznacza to, że kod działa zgodnie z oczekiwaniami. Nawet jeślinull = object
zostanie podany w miejscunull == object
, program nie będzie działał zgodnie z oczekiwaniami! Zatem nie ma sensu trzymać się tej konwencji!Jak powiedzieli inni, jest to nawyk, którego nauczył się od C, aby unikać literówek - chociaż nawet w C spodziewałbym się przyzwoitych kompilatorów na wystarczająco wysokich poziomach ostrzegawczych, aby dać ostrzeżenie. Jak mówi Chandru, porównywanie z null w Javie w ten sposób spowodowałoby problemy tylko wtedy, gdybyś używał zmiennej typu
Boolean
(której nie ma w przykładowym kodzie). Powiedziałbym, że to dość rzadka sytuacja i nie taka, dla której warto zmieniać sposób pisania kodu w innych miejscach. (Nie zawracałbym sobie głowy odwracaniem operandów nawet w tym przypadku; jeśli myślę wystarczająco jasno, aby rozważyć ich odwrócenie, jestem pewien, że mogę policzyć znaki równości).Co nie zostało wspomniane jest, że wielu ludzi (ja na pewno w zestawie) znaleźć
if (variable == constant)
formularz, aby być bardziej czytelny - jest to bardziej naturalny sposób wyrażania siebie. Jest to powód, dla którego nie należy ślepo kopiować konwencji z C. Zawsze powinieneś kwestionować praktyki (tak jak to robisz tutaj :), zanim założysz, że to, co może być przydatne w jednym środowisku, jest przydatne w innym.źródło
Nie ma to dużej wartości w Javie (1.5+), z wyjątkiem sytuacji, gdy typ obiektu to
Boolean
. W takim przypadku może to być nadal przydatne.if (object = null)
nie spowoduje błędu kompilacji w Javie 1.5+, jeśli obiekt jest,Boolean
ale wyrzuciNullPointerException
w czasie wykonywania.źródło
W Javie nie ma dobrego powodu.
Kilka innych odpowiedzi twierdziło, że dzieje się tak, ponieważ możesz przypadkowo przypisać to zadanie zamiast równości. Ale w Javie musisz mieć wartość logiczną w if, więc to:
nie będzie się kompilować.
W Javie może to mieć znaczenie tylko wtedy, gdy zmienna ma wartość logiczną:
źródło
== true
lub równie dobrze== true == true
.== true
. Ale widziałem tyle złego kodu w swojej karierze, że nie pytam już, dlaczego ktoś miałby coś napisać i po prostu akceptuję, że niektórzy napisali niepotrzebny / wątpliwy kod.x == true
za zły, ponieważ można go błędnie napisaćx = true
, nie miałoby sensu zmieniać go natrue == x
zamiast po prostux
.Dotyczy to również ściśle:
co jest wygodne, jeśli nie chcesz zajmować się NPE:
źródło
int
jest to typ prymitywny, jest istotny, ponieważ nie można wywołaćequals
na anint
, dlatego nie ma sensu dyskutować o tym,x.equals(constant)
czy użyć lubconstant.equals(x)
dlaint
wartości. W przypadkuInteger
wartości wartością domyślną jestnull
zamiast0
.Ta sztuczka miała zapobiec
v = null
rodzajom literówek.Ale Java dopuszcza tylko wyrażenia boolowskie jako
if()
warunki, więc sztuczka nie ma większego sensu, kompilator i tak znajdzie te literówki.Jest to jednak nadal cenna sztuczka dla kodu C / C ++.
źródło
Z tego samego powodu robisz to w C; przypisanie jest wyrażeniem, więc umieszczasz literał po lewej stronie, aby nie można go było nadpisać, jeśli przypadkowo użyjesz
=
zamiast==
.źródło
x
równa się5
, kiedy błędnie wpiszeszif (x = 5)
, skompiluje się po cichu (i zawsze oceni dotrue
, niezależnie od wartościx
). Jeśli jednak przyzwyczaisz się do określania najpierw literału: „if (5 = x)”, kompilator może dokładnie sprawdzić twoją pracę i zaoszczędzić ci czasu na rozwiązywanie problemów w debugerze. Nowoczesne kompilatory sprawiają, że ten nawyk jest niepotrzebny.obj
był typujava.lang.Boolean
(duże B), to może mieć znaczenie (myślę, że właściwie nie próbowałem ani nic).To jest dla osób, które wolą mieć stałą po lewej stronie. W większości przypadków posiadanie stałej po lewej stronie uniemożliwi zgłoszenie wyjątku NullPointerException (lub innego sprawdzania wartości null). Na przykład metoda String równa się również sprawdza wartość null. Posiadanie stałej po lewej stronie uniemożliwi wypisanie dodatkowego czeku. Który w inny sposób jest również wykonywany później. Posiadanie wartości null po lewej stronie jest po prostu spójne.
lubić:
źródło
Jest to warunek Yody piszący w inny sposób
W java
stan jody
źródło
Porównaj z następującym kodem:
Wyjście (po wielu wykonaniach):
Dlatego
pingResult != null
jest zwycięzcą.źródło
Ze względu na swoją przemienność jedyna różnica między
object == null
anull == object
( wersja Yoda ) ma charakter poznawczy : w jaki sposób kod jest czytany i trawiony przez czytelnika. Nie znam jednak ostatecznej odpowiedzi, ale wiem, że osobiście wolę porównywać badany obiekt z czymś innym niż porównywać coś innego z obiektem, który sprawdzam , jeśli to ma jakiś sens. Zacznij od tematu, a następnie wartości, z którą chcesz go porównać.W niektórych innych językach ten styl porównywania jest bardziej przydatny.
Aby jednak ogólnie ustrzec się przed brakującym znakiem „=”, myślę, że pisanie
null == object
jest błędnym działaniem programowania obronnego . Lepszym sposobem obejścia tego konkretnego kodu jest zagwarantowanie zachowania za pomocą testu junit. Pamiętaj, możliwy błąd polegający na pominięciu „=” nie jest zależny od argumentów wejściowych metody - nie jesteś zależny od właściwego użycia tego API przez inne osoby - więc test junit jest idealny, aby się przed tym zabezpieczyć. W każdym razie będziesz chciał napisać testy junit, aby zweryfikować zachowanie; brakujący „=” naturalnie mieści się w zakresie.źródło