Czy porównując zmienną łańcuchową z literałem łańcuchowym za pomocą .equals (), istnieje standardowa praktyka przy porządkowaniu elementów? [Zamknięte]

11

Każda z nich ma zalety i rozumiem różnice, ale co uważa się za najlepszą / standardową praktykę? I dlaczego?

Na przykład :

"myString".equals(myStringVar)
  • Unika potencjalnego NPE i nie wymaga kontroli zerowej. (Dobra rzecz?)
  • Czystszy do odczytu, ponieważ kontrola zerowa nie jest wymagana.
  • Jeśli wartość null nie jest wartością oczekiwaną, Twój program może się zepsuć, nie będąc mądrzejszym.

jednak

myStringVar.equals("myString")
  • Wymaga sprawdzenia wartości null, czy wartość null jest wartością oczekiwaną. (Dobra rzecz?)
  • Może zagracać złożone warunki warunkowe za pomocą kontroli zerowej.
  • Pozwala NPE powiadomić nas, jeśli coś się zepsuło.

Którą odmianę uważa się za standard do użycia w Javie i dlaczego?

BrandonV
źródło
2
Niezależnie od tego, czy wartość zerowa jest wartością oczekiwaną, czy operacja „równa się” powinna być miejscem, w którym można ustalić, że jest to problem?
Matthew Flynn
Nie wydaje mi się Ale to moja opinia. Chciałbym usłyszeć uzasadnienie innych.
BrandonV,
W językach, które używają = i / lub == do zadań / porównań, zwykle najlepszą praktyką jest umieszczenie rzeczy, której nie można zmienić po lewej stronie, aby nie można było wykonać przypadkowego zadania, gdy zamierzano wykonać porównanie. Dla języków, które używają metod na obiektach takich jak .equals, nie sądzę, żeby to miało znaczenie.
GordonM,

Odpowiedzi:

3

Podejrzewam, że wynika to ze środków bezpieczeństwa stosowanych podczas programowania w starszym C (lub C ++). W C możesz przypadkowo przypisać wartość, jeśli chcesz przetestować równość:

if (x = 3)

Ten warunek zawsze będzie spełniony, ponieważ jest to przypisanie x wartość 3, a nie testowanie, że x jest równe 3. Aby uniknąć tych subtelnych błędów, programiści zaczęli odwracać warunek:

if (3 = x)

Zawiera ten sam „błąd”, ale generuje błąd kompilatora, więc jest bezpieczniejszy.

Bardziej nowoczesne języki nie mają tego problemu i mogą z łatwością cię ostrzec, gdy próbujesz robić tego rodzaju rzeczy. W związku z tym nie jest to czysta preferencja, więc wybierz jedną i używaj jej konsekwentnie.

Oleksi
źródło
-1 To nie jest powód dla konwencji Java equals. W przeciwieństwie do C problem w Javie polega na tym, że wyrażenie x.equals(y)wyrzuci NPE, gdy xma wartość NULL. Jeśli masz dosłowny ciąg znaków "something"i chcesz uznać przypadek nullza „nie równy”, warto napisać, "something".equals(y)jeśli nie wiesz, czy ymoże być zerowy. To nigdy nie rzuci NPE.
Andres F.
1
  • Standardowe i dobre praktyki różnią się w zależności od kultury organizacji, w której pracujesz

  • Nasz standard w .NET wynika myStringVar == "myString"po prostu z tego, że się na to zgodziliśmy, tzn. Uważamy, że jest czysty i ugodowy

Uwaga: Nie dotyczy to Java ze względu na ==porównywanie referencji zamiast samych obiektów. W Javie powinieneś używać myStringVar.equals("myString").

CodeART
źródło
3
Przynajmniej w Javie, nie używaj, ==ponieważ porównuje tylko odwołania do obiektów. To powiedziawszy, +1 za setiment - konwencja często określa „właściwy” sposób robienia rzeczy.
Michael K
Dziękujemy za zwrócenie na to uwagi! Zaktualizowałem odpowiedź :)
CodeART
@CodeWorks: Myślę, że przegapiłeś punkt Michaela. Poza tym jest to Java, a nie JAVA.
amara
Pytanie brzmiało: „ale co uważa się za najlepszą / standardową praktykę? Dlaczego?” Moja odpowiedź jest taka, że ​​standardowe i najlepsze praktyki różnią się w zależności od organizacji. Czy się z tym nie zgadzasz?
CodeART
@CodeWorks: CodeWorks nikt nie może się z tym nie zgodzić. Ale wszyscy mogą się zgodzić, że myStringVar == "myString"jest to bardzo zły pomysł na Javę (chyba że masz absolutną pewność, że myStringVarzostał internowany).
amara
0

Myślę, że masz rację, ponieważ zależy to od semantyki nieważności zmiennej. Jeśli nie spodziewasz się, że będzie zerowy i nie będziesz musiał go sprawdzać i obsługiwać, to pierwsza forma jest czystsza.

To powiedziawszy, zamiast osadzać dosłowny ciąg znaków, lepszym rozwiązaniem byłoby prawdopodobnie:

private final String MY_STRING = "myString";
if(MY_STRING).equals(myStringVar);

Zwłaszcza jeśli istnieje możliwość użycia łańcucha w większej liczbie miejsc niż jeden.

Benjamin Wootton
źródło
2
-1: właściwie nie lepsze; dodaje bałagan o zwykle znikomej wartości
amara
@sparkleshy - Nie zgadzam się, naprawdę nie chcesz literałów łańcuchowych posypanych logiką kodu. Jak wspomniano w pierwotnej odpowiedzi, jeśli dosłowny ciąg znaków jest używany w większej liczbie miejsc niż jedna, to zdecydowanie powiedziałbym, aby je przeredagować.
Benjamin Wootton,
Aby to powiedzieć, musisz całkowicie wyłączyć Pythona, ponieważ w Pythonie identyfikatory w zasadzie są literałami łańcuchowymi. I myślę, że wszyscy musimy się zgodzić, że Python jest dobrym językiem.
amara