Metody/zmienne finalne

0

Cześć, kiedy używać final? Wiem, że przed zmiennymi ktore nie mogą być więcej zmieniane. Ale czy przy każdej zmiennej która nie będzie więcej edytowana ma być final? Od czego to zależy?

0

Final przy polach klasy używamy wtedy, jeśli nie chcemy, żeby wartość tegoż pola została zmieniona. Tak więc może się okazać że masz pole które nie jest final i nie jest zmieniane w czasie trwania programu (ale to będzie tylko przypadek, nie twój celowy zamysł). Zazwyczaj w ten sposób definiujemy pewne consty (najczęściej Stringi lub liczby).

Pamiętaj jednak, że jeśli masz pole złożone (czyli po prostu obiekt, a nie typ prosty) określone jako final, to wtedy znaczy, że później nie będzie mogło wskazywać na inny obiekt w pamięci. Ale taki obiekt będzie mógł mieć już swoje pola zmieniane (referencja do pamięci się nie zmienia).

Kolejna rzecz to oznaczanie metod jako final. Co to wtedy oznacza? Ano oznacza, że klasy dziedziczące nie będą mogły zoverridować danej metody. Z oznaczaniem metod jako final raczej rzadko się spotykałem do tej pory.

Można też całą klasę oznaczyć jako final - wówczas nie będzie można jej rozszerzyć. Ma to sens dla klas zawierających same consty bądź dla klas utilowych (czyli ogólnie - jeśli korzystamy z pól/metod klasy, a nie instancji)

1

To jest kwestia stylu. Ja na przykład stosuję zawsze kiedy mogę w polach obiektów, ale zasadniczo nigdy w parametrach czy zmiennych lokalnych, bo tam łatwo zobaczyć w których miejscach występują zmiany, a finale czytelności nie polepszają.

1

final pozwala w pewnych wypadkach kompilatorowi zoptymalizowac lepiej kod jednak nie jest to zbyt istotne poza naprawde krytycznymi zastosowaniami (zysk jest mizerny).
w praktyce:

  • oznaczam pola jako final bo jvm daje gwarancje ze inicjalizacja wydarzy sie tylko raz + bedzie widoczna dla wszystkich watkow
  • oznaczam klasy jako final bo nie projektuje ich pod katem dziedziczenia i jesli ktos kiedys wpadnie na glupi pomysl zeby sobie zrobic dziecko z moja klasa to potem pretensje moze miec tylko do siebie (bo sam musi ja pozbawic majtek, t.j. final) ;)
  • gdy juz tworze klase abstrakcyjna to widoczne metody sa albo abstract albo final (tzn. albo metoda jest po o zeby ja zdefiniowac, albo nie jest przeznaczona do nadpisania, podobna zasada co w punkcie powyzej)
  • bardzo sporadycznie uzywam final dla paramentrow/zmiennych lokalnych (czasem jest to konieczne np. ze wzgledu na przekazywanie do klasy anonimowej)
0

bardzo sporadycznie uzywam final dla paramentrow/zmiennych lokalnych (czasem jest to konieczne np. ze wzgledu na przekazywanie do klasy anonimowej)

Z tym że to było potrzebne do Java 7. W 8 wystarczy że jest effectively final.

Dodam od siebie:

  • Parametry final zapobiegają reinicjalizacji zmiennych i poprawiają przez to czytelność kodu. W kotlinie czy scali parametry są domyślnie final. Niestety w javie trzeba dodatkowo oznaczyć słowem kluczowym i to dość długim, przez co wielu osobom się nie chce. Mimo wszystko warto traktować parametry tak jakby były final.
  • W effective java był rozdział o dziedziczeniu klas i było tam wyjaśnione dlaczego klasy powinny być zaprojektowane jako do dziedziczenia, a nie losowo dziedziczone. Dlatego w kotlinie klasy są domyślnie final, a jeżeli zaprojektujemy je do dziedziczenia, to je otwieramy słowem kluczowym open. Bardzo fajne rozwiązanie.
0

Tak jak @katelx napisała... co oznacza, że w javie mam wszędzie final... czyli troszkę nonsens.

0

Co do anonimowych klas interfejsów itp http://stackoverflow.com/questions/20938095/difference-between-final-and-effectively-final
Final jest bardzo uzyteczne w wielowątkowości do tworzenia Immutable obiektów :)

1

@tdudzik
Z całym szacunkiem do wujaszka, zupełnie nie rozumiem tego toku myślenia:

  • Muszę wiedzieć która klasa jest zamknięta a która nie - ale w zamian nie zrobię nic, czego autor klasy by nie chciał.
  • Muszę wiedzieć czy coś jest nullable, czy nie - ale w zamian nie muszę tego sprawdzać na każdym kroku. W swoim kodzie i tak właściwe zwykle w 1 miejscu sprawdzam czy coś nie jest nullem, a potem po prostu tego używam. Tutaj dodatkowo pilnuje mnie język.

Przytoczony post zakłada, że programista zawsze wie co robi i się nie myli. Być może w jego zespole tak jest, wszak elita, ale niech pierwszy rzuci kamień kto nie spowodował NPE, mimo testów. Myślę że jakieś 95% programistów popełnia błędy i dobrze że jest coś co ich pilnuje. BTW, Kotlinowe null-safety to jest najlepsza rzecz jaką widziałem w ulepszeniach Javy, a taki Option nawet się nie umywa.

0

Wujek nie ogarnia, że testy są powoli passe :-)
Jak masz dobry język to wielu rzeczy nie trzeba testować bo zły kod się nie skompiluje. Tu przykład z nullem jest dobry.
Nie muszę testować obsługi nulla jak go nie mam. A można to dużo dalej pociągnąć, ale to inna historia - mainstream nie jest jeszcze na to gotowy.

0
jarekr000000 napisał(a):

Wujek nie ogarnia, że testy są powoli passe :-)

Chyba sobie żartujesz. Rozumiem że jak będziesz miał algorytm który coś rzeczywiście robi (tzn. nie mam na myśli metody która wywołuje jedną metodą) np. bierze listę, filtruje ją i coś z niej liczy to stwierdzisz że to jest OK bo tak?

0
krzysiek050 napisał(a):

Z tym że to było potrzebne do Java 7. W 8 wystarczy że jest effectively final.

przestan mi dokuczac, nie moja wina ze srednia wersja javy w korpo codebase to gdzies tak 6.5 ;)

  • Parametry final zapobiegają reinicjalizacji zmiennych i poprawiają przez to czytelność kodu (...) Mimo wszystko warto traktować parametry tak jakby były final.

mysle ze problem przypisywania do parametrow jest dosc marginalny zwlaszcza jesli sie uzywa dobrej konwencji nazewnictwa, jak bym miala dodawac final przed kazdym parameterem to juz bym sie porzygala z nudow ;)

1

jak bym miala dodawac final przed kazdym parameterem to juz bym sie porzygala z nudow ;)

Dlatego tak mało tego jest. Ludzie nie lubią pisać szumu. Ale jeżeli nie trzeba tego pisać (kotlin, scala), to czemu nie?

przestan mi dokuczac, nie moja wina ze srednia wersja javy w korpo codebase to gdzies tak 6.5 ;)

Gdy dłużej popiszesz w J8, wcześniejsze wersje odbierają chęć życia ;)

2

Immutability ma ogromne zalety, prawda dobrze znana mędrcom od języków funkcyjnych przenika i do Javy. Byłem na tym odczycie dwa lata temu - polecam jako wprowadzenie do tematu:

Niestety wymuszanie tego w Javie to trochę takie siodłanie krowy. Ja staram się, gdzie mogę, używać klas i pól finalnych, żeby nie było wątpliwosci, że ich stan jest niezmienny. Ma to walor uspokajający i z definicji eliminuje sporą kategorię bugów.

A z drugiej strony, jak napisała @katelx, walenie final przed każdym parametrem to jakaś paranoja. Jeśli ktoś robi użytek ze zmieniania wartości parametru metody, to jest WTF sam w sobie, i to nie powinno być rozwiązane żadnym słowem kluczowym, tylko zbiorową napaścią, w której winny zostanie obity marchewami z ręczników.

Gdy chodzi o zmienne, używam final nie dla kompilatora, tylko dla czytelnika - gdy chcę zwrócić tym jego uwagę, że niemutowalność zmiennej jest w jakiś sposób ważna dla rozumienia kodu.

Sianie final wszędzie gdzie się da zaowocuje tym, że nie będą już przykuwać niczyjej uwagi, tylko zrobi się ich pierdyliard - rozpaczliwy sygnał, że chyba pora po prostu zmienić język, może właśnie na Kotlin czy Scalę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1