Java pozwala oznaczać zmienne (pola / locals / parametry) jako final
, aby zapobiec ich ponownemu przypisaniu. Uważam, że jest to bardzo przydatne w przypadku pól, ponieważ pomaga mi szybko sprawdzić, czy niektóre atrybuty - lub cała klasa - mają być niezmienne.
Z drugiej strony uważam, że jest o wiele mniej przydatny w przypadku miejscowych i parametrów, i zwykle unikam oznaczania ich tak, final
jakby nawet nigdy nie zostaną ponownie przypisani (z oczywistym wyjątkiem, gdy trzeba ich użyć w klasie wewnętrznej) . Ostatnio jednak natknąłem się na kod, który używał finału, kiedy tylko jest to możliwe, co, jak sądzę, technicznie dostarcza więcej informacji.
Nie jestem już pewien swojego stylu programowania, zastanawiam się, jakie są inne zalety i wady stosowania w final
dowolnym miejscu, jaki jest najbardziej popularny styl branżowy i dlaczego.
źródło
final
czy nie, i odpowiednio je zoptymalizowałeś. Nowoczesne kompilatory są na tyle inteligentne, aby sami to wymyślić. Przynajmniej w przypadku zmiennych lokalnych,final
jest to wyłącznie z korzyścią dla ludzkich czytelników. Jeśli twoje procedury nie są zbyt skomplikowane, to większość ludzkich czytelników powinna być w stanie to sobie wyobrazić.Odpowiedzi:
Używam
final
tego samego co ty. Dla mnie wygląda to na zbędne w stosunku do lokalnych zmiennych i parametrów metody i nie przekazuje użytecznych dodatkowych informacji.Jedną ważną rzeczą jest dążenie do tego, aby moje metody były krótkie i czyste , z których każda wykonuje jedno zadanie. Zatem moje lokalne zmienne i parametry mają bardzo ograniczony zakres i są używane tylko do jednego celu. Minimalizuje to szanse na przypadkowe przypisanie ich.
Co więcej, jak zapewne wiesz,
final
nie gwarantuje, że nie możesz zmienić wartości / stanu (nieprymitywnej) zmiennej. Tyle tylko, że po zainicjowaniu nie można ponownie przypisać odwołania do tego obiektu. Innymi słowy, działa płynnie tylko ze zmiennymi typów pierwotnych lub niezmiennych. RozważaćOznacza to, że w wielu przypadkach nadal nie ułatwia to zrozumienia, co dzieje się w kodzie, a nieporozumienie może w rzeczywistości powodować subtelne błędy, które są trudne do wykrycia.
źródło
final
, dziękuję :), ale dobra uwaga na temat metod krótkich i czystych - myślę, że jeśli metoda jest na tyle krótka, że oczywiste jest, że zmienna nie jest ponownie przypisywana, istnieje nawet mniej motywu do rozważeniafinal
słowa kluczowego.Twój styl programowania Java i myśli są w porządku - nie musisz w to wątpić.
Właśnie dlatego powinieneś użyć
final
słowa kluczowego. Ci twierdzą, że TY wiesz, że nigdy nie być ponownie przydzielony, ale nikt nie wie.final
Natychmiastowe użycie ujednoznacznia twój kod.źródło
final
określa zamiar, dzięki czemu kod jest bardziej czytelny. Ponadto, gdy będziesz musiał radzić sobie z kodem z prawdziwego świata, zauważysz, że rzadko jest on nieskazitelny i przejrzysty, a swobodne dodawaniefinal
wszędzie tam, gdzie możesz, pomoże Ci wykryć błędy i lepiej zrozumieć starszy kod.final
stwierdza zamiar, co zwykle jest dobrą rzeczą w kodzie, ale wiąże się to z kosztem dodania wizualnego bałaganu. Podobnie jak większość rzeczy w programowaniu, istnieje tutaj kompromis: czy fakt, że twoja zmienna będzie używana tylko raz, będzie wart dodatkowej gadatliwości?Jedną z zalet używania
final
/const
wszędzie tam, gdzie to możliwe, jest to, że zmniejsza obciążenie umysłowe czytnika twojego kodu.Można go zapewnić, że wartość / odniesienie nigdy się nie zmieni. Nie musi więc zwracać uwagi na modyfikacje, aby zrozumieć obliczenia.
Zmieniłem zdanie na ten temat po nauce czysto funkcjonalnych języków programowania. Chłopcze, co za ulga, jeśli możesz zaufać „zmiennej”, która zawsze zachowa swoją wartość początkową.
źródło
final
nie gwarantuje się, że nie można zmienić wartości / stanu (niepodatkowej) zmiennej. Tyle tylko, że po zainicjowaniu nie można ponownie przypisać odwołania do tego obiektu.final
W parametrach metody i zmiennych lokalnych uważam szum za kod. Deklaracje metod Java mogą być dość długie (szczególnie w przypadku generyków) - nie trzeba ich już robić.Jeśli testy jednostkowe są napisane poprawnie, przypisując do parametrów, które jest „szkodliwe” będzie podniósł, więc nigdy nie powinny faktycznie być problemem. Wizualna przejrzystość jest ważniejsza niż unikanie możliwego błędu, który nie został wykryty, ponieważ twoje testy jednostkowe mają niewystarczający zasięg.
Narzędzia takie jak FindBugs i CheckStyle, które można skonfigurować tak, aby przerywały kompilację, jeśli przypisano parametry lub zmienne lokalne, jeśli bardzo zależy ci na takich rzeczach.
Oczywiście, jeśli trzeba , aby je ostateczna, na przykład dlatego, że używasz wartości w anonimowej klasy, wtedy nie ma problemu - to najprostsza najczystsze rozwiązanie.
Oprócz oczywistego efektu dodania dodatkowych słów kluczowych do parametrów, a tym samym kamuflowania ich przez IMHO, dodanie finału do parametrów metody może często spowodować, że kod w treści metody stanie się mniej czytelny, co pogorszy kod - aby był „dobry”, kod musi być tak czytelny i jak najprostszy. Dla wymyślonego przykładu, powiedzmy, że mam metodę, która musi rozróżniać przypadki bez rozróżnienia.
Bez
final
:Prosty. Czysty. Wszyscy wiedzą, co się dzieje.
Teraz z „ostateczną” opcją 1:
Podczas gdy parametry powodują, że
final
koder nie dodaje kodu dalej, niż myśli, że pracuje z pierwotną wartością, istnieje jednakowe ryzyko, że kod użyty niżej może użyćinput
zamiast tegolowercaseInput
, czego nie powinien i przed którym nie może się zabezpieczyć, ponieważ można „ t wyjąć z zakresu (lub nawet przypisaćnull
doinput
jeżeli byłoby nawet pomóc w każdym razie).Z „ostatecznym” wariantem 2:
Teraz stworzyliśmy jeszcze więcej szumu kodu i wprowadziliśmy hit wydajności związany z koniecznością wywoływania
toLowerCase()
n razy.Z „ostatecznym” wariantem 3:
Mów o szumie kodu. To jest wrak pociągu. Mamy nową metodę, wymagany blok wyjątków, ponieważ inny kod może wywołać ją niepoprawnie. Więcej testów jednostkowych w celu uwzględnienia wyjątku. Wszystko po to, by uniknąć jednej prostej, preferowanej i nieszkodliwej linii IMHO.
Istnieje również problem polegający na tym, że metody nie powinny być tak długie, aby nie można było łatwo ich wizualnie przyjąć i na pierwszy rzut oka wiedzieć, że miało miejsce przypisanie parametru.
Myślę, że dobrą praktyką / stylem jest to, że jeśli przypisujesz do parametru, robisz to na początku metody, najlepiej w pierwszym wierszu lub bezpośrednio po podstawowym sprawdzaniu danych wejściowych, skutecznie zastępując go dla całej metody, co ma spójny efekt w metoda. Czytelnicy wiedzą, że można oczekiwać, że każde zadanie będzie oczywiste (w pobliżu deklaracji podpisu) i w spójnym miejscu, co znacznie złagodzi problem, którego próbuje uniknąć dodania ostatecznego. Właściwie rzadko przypisuję parametry, ale jeśli to robię, zawsze robię to na początku metody.
Zauważ też, że
final
tak naprawdę cię nie chroni, jak mogłoby się początkowo wydawać:final
nie chroni cię całkowicie, chyba że typ parametru jest prymitywny lub niezmienny.źródło
final
zapewnia częściową gwarancję, że masz do czynienia z tą samąDate
instancją. Niektóre gwarancje są lepsze niż nic (jeśli już, to od samego początku opowiadasz się za niezmiennymi klasami!). W każdym razie w praktyce wiele z tego, co mówisz, powinno wpływać na istniejące niezmienne domyślnie języki, ale tak nie jest, co oznacza, że to nie jest problem.final
, z możliwością uczynienia ich niekończącymi się dla przypadków takich jak powyżej. Po prostu nie warto spamować podpisu słowem kluczowym.Pozwalam zaćmieniu umieścić
final
przed każdą zmienną lokalną, ponieważ uważam, że ułatwia to czytanie programu. Nie robię tego z parametrami, ponieważ chcę, aby lista parametrów była jak najkrótsza, idealnie powinna pasować do jednej linii.źródło
var
oznaczanie zmiennych nie-końcowych. YMMV.var
! Niestety w Javie nie jest to ustawienie domyślne, a teraz jest już za późno na zmianę języka. Dlatego jestem gotów znieść drobną niedogodność związaną z pisaniemfinal
:)final
słowo kluczowe wcześniej, a tylko 10-20% potrzebujevar
...