2014-04-18 29 views
33

Mi chiedo perché questo è bene:Perché il metodo privato può essere definitivo?

class SomeClass { 

    //--snip-- 

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

Se è privata, non c'è modo chiunque può ignorare, giusto?

Perché è possibile aggiungere la parola chiave final se non ha alcun effetto? (o mi manchi qualcosa?)

+0

ancora potrebbe essere cambiato con nella classe Io parto dal presupposto – 3kings

+8

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

+4

possibile duplicato di [Fai metodi privati ​​finali?] (http://stackoverflow.com/questions/1984464/make-private-methods-final) –

risposta

42

Fondamentalmente, è permesso perché non pensava che valesse la pena mettere un caso speciale che vieta il modificatore private. È come come è possibile dichiarare metodi su un'interfaccia come public o classi nidificate in un'interfaccia come static, anche se tali parole chiave sono implicite nelle interfacce. È anche possibile dichiarare i metodi final su una classe final, ecc.

Java ha preso la posizione di non lamentarsi quando si aggiungono modificatori ridondanti. Lo fanno costantemente.

+12

'modificatori ridondanti' ha chiarito molto ... grazie –

+0

Inoltre, l'ispezione del codice" si lamenta "di questo. – Delfic

4

Rende la lingua più flessibile ma la lingua non garantisce che avrà alcun effetto. Creare un metodo privato final è un suggerimento per il compilatore (JIT).

Il linguaggio Java Specification notes che:

Un metodo può essere dichiarato finale per impedire alle sottoclassi di sostituire o di nasconderlo.

È un errore in fase di compilazione per tentare di sovrascrivere o nascondere un metodo finale.

Un metodo privato e tutti i metodi dichiarati immediatamente all'interno di una classe finale (§8.1.1.2) si comportano come se fossero definitivi, poiché è impossibile sovrascriverli.

In fase di esecuzione, un generatore di codice macchina o un ottimizzatore può "allineare" il corpo di un metodo finale, sostituendo un'invocazione del metodo con il codice nel suo corpo. Il processo di inlining deve preservare la semantica dell'invocazione del metodo. In particolare, se la destinazione di una chiamata al metodo di istanza è nullo, è necessario generare una NullPointerException anche se il metodo è in linea. Un compilatore Java deve garantire che l'eccezione venga lanciata nel punto corretto, in modo che gli argomenti effettivi al metodo vengano visti essere stati valutati nell'ordine corretto prima dell'invocazione del metodo.

From Wikipedia:

Un errore comune è che dichiara una classe o metodo finale migliora l'efficienza consentendo al compilatore di inserire direttamente il metodo ovunque viene chiamato (vedi espansione linea). Ma poiché il metodo viene caricato in fase di runtime, i compilatori non sono in grado di farlo. Solo l'ambiente runtime e compilatore JIT sanno esattamente quali classi sono stati caricati, e quindi solo loro sono in grado di prendere decisioni su quando in linea, se il metodo è finale

compilatori codice macchina che generano direttamente eseguibile , codice macchina specifico per piattaforma, sono un'eccezione. Quando si utilizza il collegamento statico , il compilatore può presumere che metodi e variabili computabili in fase di compilazione possano essere inline.

+2

Poiché i metodi privati ​​sono trattati come definitivi, non è necessario il "final" su di essi per dare a JIT un suggerimento di poterli allineare. La tua risposta suggerisce che l'utilizzo di finali privati ​​potrebbe essere vantaggioso, ma il testo che citi dice diversamente. – Kevin

3

Un caso limite che richiede che un metodo privato sia definitivo è quando viene utilizzata l'annotazione SafeVarargs. Il seguente codice non viene compilato, perché il metodo privato non è definitivo.

@SafeVarargs 
private void method(List<String>... stringLists) { 
    //TODO a safe varargs operation 
} 
Problemi correlati