2013-07-31 12 views

risposta

10

L'accesso ai membri privati ​​da un'altra classe è leggermente più complicato perché la JVM in realtà non lo consente. Di conseguenza il compilatore inietta metodi di accesso che lo rendono leggermente più lento o la traccia dello stack più complicata.

Per questo motivo lo lascio come pacchetto locale.

BTW Il costruttore di un abstract class non deve necessariamente essere public. Può anche essere protected o pacchetto locale

private static class A { 
    private A() { 
     throw new Error(); 
    } 
} 
public static void main(String... ignored) { 
    new A(); 
} 

stampa un elemento in più dello stack trace.

Exception in thread "main" java.lang.Error 
    at Main$A.<init>(Main.java:8) 
    at Main$A.<init>(Main.java:6) 
    at Main.main(Main.java:12) 

Rendere locale il pacchetto costruttore e il secondo scompare.

+0

Perché viene prodotta la riga aggiuntiva della traccia dello stack? Come funziona? Ho riconosciuto che la linea in eccesso si verifica solo se la definisco privata. Solo per due linee protette. Quindi significa che la definizione di private diminuisce l'efficienza? Perché il compilatore JVM consente di definire il costruttore di tali classi con visibilità> = protetto? –

+1

@ ŁukaszRzeszotarski La JVM non consente l'accesso privato da un'altra classe. Ciò che il javac fa per aggirare questo è generare metodi sintetici che non sono privati ​​che possono essere chiamati. Questi ottengono un numero di riga dell'inizio della classe. Il metodo generato chiama il metodo reale. Lo fa per tutti i membri privati. Mentre più lento nella modalità interpretata, una volta ottimizzato il metodo supplementare è inline e non ha alcun impatto per quanto ne so, tranne sui sistemi JME dove la sua non è abbastanza intelligente per fare questo. –

+0

Ora è chiaro. Ho visto il bytecode della classe e quello che veramente mi ha sorpreso è che il bytecode contiene ulteriore metodo solo se si tenta di creare un'istanza della classe (nel metodo principale per esempio). –

9

Per quanto riguarda le altre classi, non dovrebbe, poiché la classe interna è dichiarata come privata. Non riescono a vederlo affatto.

Non dovrebbe fare la differenza per la classe di chiusura poiché contiene la classe interna.

+2

Basta notare, se il costruttore di classe è contrassegnata come 'private', qualche strumento per la codifica di verifica standard come [checkstyle] (http://checkstyle.sourceforge.net/) può suggerire per contrassegnare la classe come' final' anche. –

Problemi correlati