Czy mogę pominąć nawiasy klamrowe w Javie? [Zamknięte]

84

Szukałem tego, ale nie mogłem znaleźć odpowiedzi iz jakiegoś powodu wstydziłem się zapytać profesora z powodu tego uczucia, gdy setki ludzi gapią się na ciebie ...

W każdym razie moje pytanie brzmi: jakie jest znaczenie posiadania nawiasów? Czy mogę je pominąć? Przykład:

for (int i = 0; i < size; i++)  {
   a += b;
}

vs

for (int i = 0; i < size; i++)
   a += b;

Wiem, że oba będą działać, ale jeśli pominę nawiasy (co robię często, ze względu na widoczność), czy to coś zmieni, cokolwiek? Jak powiedziałem, wiem, że to działa, testowałem to kilkadziesiąt razy, ale teraz część moich zadań na studiach się rozrasta iz jakiegoś powodu mam irracjonalny strach, że na dłuższą metę to moja przyczyna problemów? Czy jest powód, żeby się tego obawiać?

vedran
źródło
Zawsze używam programu formatującego kod w celu zapewnienia czytelności, ponieważ rozwiązuje to wiele potencjalnych przyczyn nieporozumień. To może sprawić, że używanie nawiasów klamrowych stanie się zbędne
Peter Lawrey

Odpowiedzi:

149

Nie zmieni to w ogóle niczego poza możliwością utrzymania twojego kodu. Widziałem taki kod:

for (int i = 0; i < size; i++)
   a += b;
   System.out.println("foo");

co oznacza to:

for (int i = 0; i < size; i++)
   a += b;
System.out.println("foo");

... ale co powinno być takie:

for (int i = 0; i < size; i++) {
   a += b;
   System.out.println("foo");
}

Osobiście zawsze umieszczam nawiasy, aby zmniejszyć możliwość pomyłki podczas czytania lub modyfikowania kodu.

Wymagały tego konwencje kodowania obowiązujące w każdej firmie, w której pracowałem - co nie oznacza, że ​​niektóre inne firmy nie mają innych konwencji ...

I na wszelki wypadek, gdybyś pomyślał, że to nigdy nie zrobi różnicy: musiałem raz naprawić błąd, który był prawie równoważny z powyższym kodem. Było to niezwykle trudne do wykrycia ... (co prawda było to lata temu, zanim zacząłem testy jednostkowe, co bez wątpienia ułatwiłoby diagnozowanie).

Jon Skeet
źródło
13
@vedran: Więc jesteś świadomy problemu, ale zakładasz, że nigdy Cię nie ugryzie? I że każdy, kto czyta Twój kod, będzie wiedział, czego się spodziewać? Mówię tylko - jest powód, dla którego są one wymagane w konwencjach kodowania, z którymi pracowałem :)
Jon Skeet
12
Po prostu czułem się jak prywatny sierżant, z którym rozmawiał. Tak, chociaż jest to dla mnie wygodniejsze, inni z mojej grupy uważają to za irytujące i problematyczne. Od teraz będę wszędzie używać nawiasów.
vedran
13
@vedran fajna metafora, poza tym, że Jon Skeet nie jest sierżantem, on jest naczelnym dowódcą :-)
stivlo
5
@stivlo Och, jestem pewien, że jego łaska wybaczy drobne nieposłuszeństwo;) Osobiście umieszczam nawiasy po stwierdzeniach, ponieważ jest to część każdego przewodnika po kodowaniu, jaki kiedykolwiek widziałem, ale myślę, że dziś jest to dość słaby argument. Dzięki automatycznemu formatowaniu kodu wszędzie, i tak nigdy nie powinieneś widzieć kodu w jego pierwszej formie, a jeśli wcięcie jest poprawne, nawiasy nie podają żadnych dodatkowych informacji.
Voo
4
Więcej argumentów, aby ZAWSZE używać nawiasów klamrowych: imperialviolet.org/2014/02/22/applebug.html
MrTJ
32

Używanie nawiasów klamrowych sprawia, że ​​kod jest łatwiejszy w utrzymaniu i zrozumiały. Dlatego powinieneś rozważyć je domyślnie .

Czasami pomijam nawiasy klamrowe w klauzulach ochronnych, aby kod był bardziej zwarty. Wymagam, aby były to ifinstrukcje, po których następuje instrukcja skoku , taka jak returnlub throw. Trzymam je również w tej samej linii, aby zwrócić uwagę na idiom, np .:

if (!isActive()) return;

Dotyczy to również kodu wewnątrz pętli:

for (...) {
  if (shouldSkip()) continue;
  ...
}

I do innych warunków przeskoku z metod, które niekoniecznie znajdują się na górze treści metody.

Niektóre języki (takie jak Perl czy Ruby) mają rodzaj instrukcji warunkowej , w której nawiasy klamrowe nie mają zastosowania:

return if (!isActive());
// or, more interestingly
return unless (isActive());

Uważam, że jest to równoważne temu, co właśnie opisałem, ale wyraźnie poparte przez język.

Jordão
źródło
7
Klauzule ochronne +1 wewnątrz pętli są zwykle bardziej przejrzyste bez nawiasów klamrowych.
Viccari
2
Uzgodniono klauzule ochronne. Moim zdaniem sprawia, że ​​kod jest bardziej czytelny i faktycznie zwiększa łatwość utrzymania. Punkty, które czyni przyjęta odpowiedź, są jednak bardzo ważne, więc ograniczyłbym pominięcie nawiasów klamrowych do klauzul ochronnych.
ChrisK,
11

Nie ma różnicy. Główny problem z drugą wersją polega na tym, że możesz napisać to:

for (...) 
  do_something();
  do_something_else();

kiedy aktualizujesz tę metodę, myślisz, że do_something_else()jest wywoływana wewnątrz pętli. (A to prowadzi do niesamowitych sesji debugowania).

Jest jeszcze jeden problem, którego nie ma wersja z nawiasami klamrowymi, a prawdopodobnie jest jeszcze trudniejszy do wykrycia:

for (int i=0; i<3; i++);
  System.out.println("Why on earth does this print just once?");

Więc trzymaj szelki, chyba że masz dobry powód, to tylko kilka naciśnięć klawiszy więcej.

Mata
źródło
3
Pierwsza kwestia jest dobra, ale druga jest błędna. Wersja z nawiasami klamrowymi może nadal mieć ten problem. dla (int i = 0; i <3; i ++); {System.out.println ("Dlaczego to jest drukowane tylko raz?"); }. Wiem, bo zawsze używam nawiasów klamrowych, ale czasami błędnie dodaję dodatkowe średniki.
emory
3
Wersja z klamrami może to mieć, ale jest to bardziej widoczne, jeśli klamra znajduje się w tej samej linii. Z nawiasem klamrowym w następnym wierszu rzeczywiście jest tak samo paskudny.
Mat
Druga wersja jest dla mnie równie ważna, jak pierwsza, ponieważ patrząc na drugą, prawie niemożliwe jest dostrzeżenie, co jest nie tak, dopóki nie uruchomisz jej, aby zobaczyć, co się dzieje na świecie. Programiści spędzają dużo czasu na debugowaniu kodu, który zostałby łatwo zauważony, gdyby wprowadzono te zawijane nawiasy. Dla mnie pomijanie tych zawijanych nawiasów jest nie tylko kwestią stylu, ale dobrym wskaźnikiem prawdopodobnego błędnego kodu.
theyCallMeJun
5

Myślę, że gubienie nawiasów klamrowych jest dobre, jeśli używasz również automatycznego formatowania, ponieważ twoje wcięcie jest zawsze poprawne, więc łatwo będzie wykryć błędy w ten sposób.

Mówienie, że pozostawienie nawiasów klamrowych jest złe, dziwne lub nieczytelne, jest po prostu błędne, ponieważ cały język jest oparty na tym pomyśle i jest dość popularny (python).

Ale muszę powiedzieć, że bez użycia formatera może to być niebezpieczne.

Máté Magyar
źródło
Wcięcia mają znaczenie w Pythonie. W Javie, C, C ++ lub innych językach w stylu C tak nie jest.
Christopher Schneider
1
@ChristopherSchneider To jest pont.
Máté Magyar
5

W większości przypadków podane dotychczas odpowiedzi są poprawne. Ale z punktu widzenia bezpieczeństwa ma pewne wady. Pracując w zespole płatności, bezpieczeństwo jest znacznie silniejszym czynnikiem motywującym do podejmowania takich decyzji. Powiedzmy, że masz następujący kod:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )

Teraz powiedzmy, że ten kod nie działa z powodu jakiegoś wewnętrznego problemu. Chcesz sprawdzić dane wejściowe. Więc wprowadzasz następującą zmianę:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )
  Logger.log( creditCardInput )

Powiedzmy, że naprawiasz problem i wdrażasz ten kod (a może recenzent i myślisz, że to nie spowoduje problemu, ponieważ nie znajduje się w stanie „Prod”). W magiczny sposób dzienniki produkcyjne drukują teraz informacje o karcie kredytowej klienta, które są widoczne dla wszystkich pracowników, którzy mogą je przeglądać. Nie daj Boże, jeśli któryś z nich (w złym zamiarze) zdobędzie te dane.

Dlatego brak nawiasu klamrowego i trochę nieostrożnego kodowania często może prowadzić do naruszenia bezpieczeństwa informacji. Został również sklasyfikowany jako podatność w JAVA przez CERT - Software Engineering Institure, CMU .

kung_fu_coder
źródło
Twierdzę, że to po pierwsze dość okropny projekt, ale punkt jest ważny.
Christopher Schneider,
4

Jeśli masz jedną instrukcję, możesz pominąć nawiasy, w przypadku więcej niż jednej instrukcji nawiasy są niezbędne do zadeklarowania bloku kodu.

Używając nawiasów, deklarujesz blok kodu:

{

//Block of code
}

Nawiasów należy używać również z tylko jedną instrukcją, gdy znajdujesz się w sytuacji zagnieżdżonej instrukcji, aby poprawić czytelność, na przykład:

for( ; ; )
  if(a == b) 
    doSomething()

jest bardziej czytelny w nawiasach również, jeśli nie jest to konieczne:

for( ; ; ) {
  if(a == b) {
    doSomething()
   }
}
aleroot
źródło
4

Jeśli używasz nawiasów, twój kod jest bardziej czytelny. A jeśli chcesz dodać operatora w tym samym bloku, możesz uniknąć możliwych błędów

Sergey Gazaryan
źródło
3

Użycie nawiasów w przyszłości zabezpiecza kod przed późniejszymi modyfikacjami. Widziałem przypadki, w których pominięto nawiasy, a ktoś później dodał jakiś kod i nie umieścił nawiasów w tym czasie. W rezultacie dodany przez nich kod nie trafił do sekcji, o której myśleli. Myślę więc, że odpowiedź jest taka, że ​​jest to dobra praktyka w świetle przyszłych zmian w kodzie. Widziałem, jak grupy oprogramowania przyjmują to jako standard, tj. Z tego powodu zawsze wymagają nawiasów nawet w przypadku bloków pojedynczych linii.

Nerdtron
źródło
Zgadzam się z tym. Nawiasy nie są dla Ciebie. Są dla osoby, która jest za tobą. Kilka razy miałem kod, który utrzymywałem, i nie byłem zaznajomiony z kodem, który nie zawierał nawiasów i miał złe wcięcia. Na tym etapie prawdopodobnie naprawiam błąd, więc dobrze jest wiedzieć, co ma się stać. Pominięcie nawiasów klamrowych sprawia, że ​​jest to mniej oczywiste i muszę przechodzić przez kod, marnując czas.
Christopher Schneider
2

Więcej wsparcia dla grupy „always braces” ode mnie. Jeśli pominiesz nawiasy klamrowe dla pętli / gałęzi z pojedynczą instrukcją, umieść instrukcję w tym samym wierszu, co instrukcja sterująca,

if (condition) doSomething();
for(int i = 0; i < arr.length; ++i) arr[i] += b;

w ten sposób trudniej jest zapomnieć o wstawieniu nawiasów klamrowych, gdy ciało jest rozszerzone. Mimo to i tak używaj curlies.

Daniel Fischer
źródło
2

używanie redundantnych nawiasów klamrowych w celu stwierdzenia, że ​​kod jest łatwiejszy w utrzymaniu, rodzi następujące pytanie: jeśli osoby piszące, zastanawiające się i utrzymujące kod mają problemy takie jak opisane wcześniej (związane z wcięciami lub czytelnością), być może w ogóle nie powinni programować. .


źródło
1

Jeśli chodzi o wynik, to jest to samo.

Tylko dwie rzeczy do rozważenia.

- Obsługa kodu
- luźno powiązany kod. (może wykonać coś innego, ponieważ nie określono zakresu pętli).

Uwaga: w mojej obserwacji, jeśli jest to pętla z w pętli. Wewnętrzna pętla bez szelek jest również bezpieczna. Wynik nie będzie się różnić.

Sireesh Yarlagadda
źródło
1

Jeśli masz tylko jedną instrukcję wewnątrz pętli, to jest taka sama.

Na przykład zobacz następujący kod:

for(int i=0;i<4;i++)
            System.out.println("shiva");

w powyższym kodzie mamy tylko jedno stwierdzenie. więc nie ma problemu

for(int i=0;i<4;i++)
            System.out.println("shiva");
            System.out.println("End");

Tutaj mamy dwie instrukcje, ale tylko pierwsza instrukcja wchodzi do pętli, a druga nie.

Jeśli masz wiele instrukcji w jednej pętli, musisz użyć nawiasów klamrowych.

NShiva
źródło
1

Jeśli usuniesz nawiasy klamrowe, odczyta tylko pierwszy wiersz instrukcji. Żadne dodatkowe wiersze nie zostaną odczytane. Jeśli masz więcej niż 1 linię instrukcji do wykonania, użyj nawiasu klamrowego - w przeciwnym razie zostanie wyrzucony wyjątek.

Ashish Patel
źródło
1

W dzisiejszych czasach bardzo łatwo jest ponownie wprowadzić wcięcia kodów, aby dowiedzieć się, który blok kodów jest w którym iflub for/ while. Jeśli upierasz się, że ponowne wcięcie jest trudne, to nawiasy umieszczone w niewłaściwym wcięciu mogą równie mocno zmylić cię.

for(int i = 0; i < 100; i++) { if(i < 10) {
    doSomething();
} else { for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}}

Jeśli zrobisz to wszędzie, twój mózg się rozpadnie w mgnieniu oka. Nawet w przypadku nawiasów, jesteś zależny od wcięcia, aby wizualnie znaleźć początek i koniec bloków kodu.

Jeśli wcięcie jest ważne, powinieneś już napisać kod z odpowiednim wcięciem, aby inne osoby nie musiały ponownie wciskać kodów, aby poprawnie odczytać.

Jeśli chcesz argumentować, że poprzedni przykład jest zbyt fałszywy / celowy i że nawiasy są po to, aby uchwycić nieostrożny problem z wcięciami (szczególnie podczas kopiowania / wklejania kodów), rozważ to:

for(int i = 0; i < 100; i++) {
    if(i < 10) {
    doSomething();
}
else {
    for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}

Tak, wygląda mniej poważnie niż w poprzednim przykładzie, ale takie wcięcie może Cię zmylić.

IMHO, obowiązkiem osoby piszącej kod jest sprawdzenie kodu i upewnienie się, że elementy są prawidłowo wcięte, zanim przystąpią do innych czynności.

Jai
źródło
0

odruchem powinno być również przeformatowanie kodu ... to jest oczywiście dla profesjonalnych programistów w profesjonalnych zespołach


źródło
0

Prawdopodobnie najlepiej jest używać nawiasów klamrowych wszędzie ze względu na prosty fakt, że debugowanie byłoby wyjątkowo uciążliwe. Ale z drugiej strony jeden wiersz kodu niekoniecznie wymaga nawiasu. Mam nadzieję że to pomoże!

Ash_s94
źródło