2014-04-18 14 views
33

Zastanawiam się, dlaczego to jest w porządku:Dlaczego metoda prywatna może być ostateczna?

class SomeClass { 

    //--snip-- 

    private final void doStuff() 
    { 
     // private work here 
    } 
} 

Jeśli jest prywatny, nie ma mowy, każdy może go zastąpić, prawda?

Dlaczego jest możliwe dodanie słowa kluczowego final, jeśli nie ma ono żadnego efektu? (lub coś mi brakuje?)

+0

nadal mogła być zmieniona w klasie jestem zakładając – 3kings

+8

http://www.javaworld.com/article/2077399/core-java/private-and-final.html – Jeffrey

+4

możliwe duplikat [Marka prywatne metody końcowe?] (http://stackoverflow.com/questions/1984464/make-private-methods-final) –

Odpowiedz

42

Zasadniczo jest to dozwolone, ponieważ nie czuli, że warto umieścić specjalny przypadek, który zabrania modyfikatorowi private. To tak, jak można również zadeklarować metody na interfejsie jako public lub zagnieżdżone klasy w interfejsie jako static, nawet jeśli te słowa kluczowe są implikowane w interfejsach. Możesz także zadeklarować metody final na klasie final itp.

Java przyjęła stanowisko nie narzekające, gdy dodajesz zbędne modyfikatory. Robią to konsekwentnie.

+12

'Redundantne modyfikatory' wyjaśniły wiele .. dzięki –

+0

Ponadto kontrola kodu" narzeka "na ten temat. – Delfic

4

Dzięki temu język jest bardziej elastyczny, ale język nie gwarantuje jego skuteczności. Sporządzenie prywatnego ostatecznego sposobu jest wskazówką dla kompilatora (JIT).

Java Language Specification notes że:

Metoda może być uznana za końcowy, aby zapobiec podklasy z nadrzędnymi lub ukrywanie go.

Jest to błąd podczas kompilacji, aby próbować przesłonić lub ukryć ostateczną metodę.

Prywatna metoda i wszystkie metody zadeklarowane bezpośrednio w klasie końcowej (§8.1.1.2) zachowują się tak, jakby były ostateczne, ponieważ nie można ich zastąpić.

W czasie wykonywania generator kodu maszynowego lub optymalizator może "wstawić" treść ostatniej metody, zastępując wywołanie metody kodem w jego treści. Proces wstawiania musi zachować semantykę wywołania metody. W szczególności, jeśli obiekt docelowy wywołania metody instancji ma wartość NULL, należy wygenerować wyjątek NullPointerException, nawet jeśli metoda jest wbudowana. Kompilator Java musi zapewnić, że wyjątek zostanie zgłoszony we właściwym punkcie, tak że rzeczywiste argumenty metody zostaną ocenione w prawidłowej kolejności przed wywołaniem metody.

From Wikipedia:

Typowym błędne że oświadczenie klasę lub sposób, jak końcowa zwiększa wydajność, umożliwiając kompilator może bezpośrednio wprowadzić metodą gdzie jest on jako (patrz inline pęcznienie). Ale ponieważ metoda jest ładowana w czasie wykonywania, kompilatory nie mogą tego zrobić. Tylko Środowisko wykonawcze i JIT kompilator dokładnie wiedzieć, które klasy są został załadowany, a więc tylko one są w stanie podejmować decyzje o tym, kiedy inline, czy metoda jest ostateczna

kodu maszynowego kompilatory generujące bezpośrednio wykonywalny specyficzny dla platformy kod maszynowy jest wyjątkiem. Podczas korzystania z łączenia statycznego kompilator może bezpiecznie założyć, że metody i zmienne obliczane podczas kompilacji mogą być wstawiane.

+2

Ponieważ metody prywatne są traktowane jako ostateczne, nie trzeba ich "kończyć", aby dać JIT wskazówkę, że można je włączyć. Twoja odpowiedź sugeruje, że prywatny finał może być korzystny, ale cytowany tekst mówi inaczej. – Kevin

3

Jeden przypadek krawędzi, który wymaga ostatecznej metody prywatnej, jest stosowany do adnotacji SafeVarargs. Poniższy kod nie jest kompilowany, ponieważ metoda prywatna nie jest ostateczna.

@SafeVarargs 
private void method(List<String>... stringLists) { 
    //TODO a safe varargs operation 
} 
Powiązane problemy