Ponieważ final
kilka lat temu odkryłem moc słowa kluczowego w Javie, pomogło mi to uczynić moje kody o wiele bardziej czytelnymi, ponieważ ludzie mogą łatwo zobaczyć, które zmienne są tylko do odczytu. Może to również nieco poprawić działanie JIT i chociaż jest to bardzo ograniczone, nie może zaszkodzić, szczególnie podczas atakowania na urządzenia wbudowane, takie jak platformy Android.
Ale przede wszystkim przyczynia się do uczynienia projektu bardziej odpornym na zmiany i kieruje innymi osobami odpowiedzialnymi za modyfikację bazy kodu.
Jednak podczas przeglądania kodu źródłowego JDK nigdy nie natknąłem się na to słowo kluczowe, ani w odniesieniu do klas, metod, ani zmiennych. To samo dotyczy różnych systemów, które musiałem sprawdzić.
Czy jest powód? Czy jest to powszechny paradygmat projektowania, aby wszystko można było modyfikować od wewnątrz?
final
pól ma taką samą semantykę jak pisanievolatile
pola, a następnie czytanie ich później musi mieć zmienną semantykę odczytu, to nie zawsze to, czego chceszOdpowiedzi:
Podejrzewam, że powodem, dla którego go nie widzisz, jest to, że JDK został zaprojektowany do rozszerzenia (jest to podstawa, na której zbudowane są wszystkie twoje programy). Korzystanie z niego przez kod aplikacji nie byłoby niczym niezwykłym. Nie spodziewałbym się również, że zobaczę go dużo w kodzie biblioteki (ponieważ biblioteki są również często zaprojektowane do rozszerzenia).
Spójrz na kilka dobrych projektów open source i myślę, że znajdziesz więcej.
W przeciwieństwie do tego, co widzisz w Javie, w świecie .NET wielokrotnie słyszałem argument, że klauzule powinny być
sealed
(podobne do ostatecznego zastosowania do klasy) domyślnie i że programista powinien jawnie odblokować to.źródło
final
na polach, a nie na metodach. Niezmienne klasy mogą być również zaprojektowane do przedłużenia.Problem z używaniem
final
do przekazywania, że coś jest tylko do odczytu, polega na tym, że tak naprawdę działa tylko dla prymitywnych typów, takich jakint
,char
itp. Do wszystkich obiektów w Javie faktycznie używa się wskaźnika (rodzaju). W rezultacie, gdy używaszfinal
słowa kluczowego na obiekcie, mówisz tylko, że odwołanie jest tylko do odczytu, a sam obiekt jest nadal zmienny.Mógłby zostać użyty częściej, gdyby faktycznie uczynił obiekt tylko do odczytu. W C ++ właśnie to
const
działa, w wyniku czego jest to o wiele bardziej użyteczne i często używane słowo kluczowe.Jednym miejscem, w którym często używam
final
słowa kluczowego, są parametry, aby uniknąć nieporozumień spowodowanych przez takie rzeczy:W tym przykładzie wydaje się oczywiste, dlaczego to nie działa, ale jeśli
someMethod(FancyObject)
jest duże i może dojść do skomplikowanego zamieszania. Dlaczego tego nie uniknąć?Jest to również część standardów kodowania Sun (lub Oracle, jak sądzę teraz).
źródło
final
klasy API Java były częściej używane , większość obiektów była niezmienna, jak w przypadku wielu bibliotek Scala. Następnie utworzenie pól obiektowychfinal
sprawia, że klasa jest niezmienna w wielu przypadkach. Ten projekt jest już używany wBigDecimal
iString
.Zgadzam się, że
final
słowo kluczowe poprawia czytelność. Ułatwia to zrozumienie, kiedy obiekt jest niezmienny. Jednak w Javie jest bardzo gadatliwy, szczególnie (moim zdaniem), gdy jest używany w parametrach. Nie oznacza to, że ludzie nie powinni go używać, ponieważ jest pełny, ale raczej go nie używają, ponieważ jest pełny.Niektóre inne języki, takie jak scala, znacznie ułatwiają składanie ostatecznych deklaracji ( val ). W tych językach końcowe deklaracje mogą być bardziej powszechne niż zmienne.
Pamiętaj, że istnieje wiele różnych zastosowań końcowego słowa kluczowego. Twój post obejmuje głównie pozycje 2 i 3.
źródło
Na początek oficjalne konwencje Java Code nie faworyzują ani nie zabraniają określonego użycia
final
. Oznacza to, że programiści JDK mogą dowolnie wybierać preferowany sposób.Nie umiem czytać w ich myślach, ale dla mnie preferencja dotycząca tego, czy korzystać,
final
czy nie, była kwestią skupioną. To, czy mam wystarczająco dużo czasu, aby całkowicie skoncentrować się na kodzie, czy nie .final
jako śmieci, które po prostu zaciemniają rzeczy, które są już wystarczająco wyraźnie wyrażone w kodzie. Wygląda na to, że programiści JDK również należą do tej kategorii.Z drugiej strony było zupełnie odwrotnie w innym projekcie, w którym spędziliśmy godzinę na 100 liniach kodu. Tam zastałem strzelanie
final
jak pistolet maszynowy we własnym i innym kodzie - po prostu dlatego, że był to najszybszy sposób na wykrycie zamiaru faceta, który napisał go przede mną, i, podobnie, najszybszy sposób na przekazanie moich własnych zamiarów facet, który później będzie pracował nad moim kodem.Rozumowanie jak powyżej jest śliskie. Przedwczesna optymalizacja może zaszkodzić; Donald Knuth posuwa się nawet do nazwania go „źródłem wszelkiego zła” . Nie pozwól, żeby cię to uwięziło. Napisz głupi kod .
źródło
Ostatnio odkryłem radość z funkcji „Zapisz działania” w środowisku Eclipse IDE. Mogę zmusić go do przeformatowania kodu, wstawienia brakujących
@Override
adnotacji i zrobienia kilku fajnych rzeczy, takich jak usuwanie niepotrzebnych nawiasów w wyrażeniach lub umieszczaniefinal
słowa kluczowego wszędzie za każdym razem, gdy kliknęctrl + S
. Aktywowałem niektóre z tych wyzwalaczy i, chłopcze, to bardzo pomaga!Okazało się, że wiele z tych wyzwalaczy działa jak szybkie sprawdzenie poprawności mojego kodu.
ctrl + s
? - być może gdzieś schrzaniłem typy parametrów!final
. Czy musi zmienić swoją wartość?Okazało się, że im mniej zmiennych, tym mniej problemów mam w czasie debugowania. Ile razy śledziłeś wartość jakiejś zmiennej tylko po to, by stwierdzić, że zmienia się ona jakoś powiedzmy od 5 do 7? „Jak do cholery może być ?!” zadajesz sobie pytanie i spędzasz kolejne kilka godzin wchodząc i wychodząc z niezliczonych metod, aby dowiedzieć się, że popełniłeś błąd w swojej logice. Aby to naprawić, musisz dodać jeszcze jedną flagę, kilka warunków i ostrożnie zmienić niektóre wartości tu i tam.
Och, nienawidzę debugowania! Za każdym razem, gdy uruchamiam debuger, mam wrażenie, że mój czas się kończy i rozpaczliwie potrzebuję tego czasu, aby spełnić przynajmniej niektóre z moich marzeń z dzieciństwa! Do diabła z debugowaniem!
final
oznacza koniec tajemniczych zmian wartości. Więcejfinal
s => mniej wątłych części w moim kodzie => mniej błędów => więcej czasu na robienie dobrych rzeczy!Jeśli chodzi o
final
zajęcia i metody, nie obchodzi mnie to. Uwielbiam polimorfizm. Polimorfizm oznacza ponowne użycie oznacza mniej kodu oznacza mniej błędów. JVM i tak wykonuje całkiem dobrą robotę z dewitualizacją i wprowadzaniem metod, więc nie widzę wartości w zabijaniu możliwości ponownego użycia kodu dla nieoczekiwanych korzyści wydajnościowych.Widzenie wszystkich tych
final
znaków w kodzie na początku trochę rozprasza i wymaga czasu, aby się przyzwyczaić. Niektórzy z moich kolegów z zespołu wciąż są bardzo zaskoczeni, widząc tak wielefinal
słów kluczowych. Żałuję, że nie było w IDE ustawienia dla specjalnego kolorowania składni. Z przyjemnością przestawię go na odcień szarości (np. Adnotacje), aby nie rozpraszały się podczas czytania kodu. Eclipse ma obecnie osobny kolor dlareturn
i wszystkich innych słów kluczowych, ale nie dlafinal
.źródło
do
notacją można zrobić wszystko, co niezbędne : Jasne, Java nie jest najlepszym językiem do pisania w funkcjonalnym stylu, ale przynajmniej pozwala pisać solidny kod - i to jest to, na czym mi naprawdę zależy.