2014-12-15 16 views
41

In che modo il compilatore non si lamenta quando scrivo il seguente codice?Come è accessibile questa variabile privata?

public class MyClass 
{ 
    private int count; 

    public MyClass(int x){ 
     this.count=x; 
    } 

    public void testPrivate(MyClass o){ 
     System.out.println(o.count); 
    } 
} 

Anche se è un'istanza della stessa classe in cui testPrivate è scritto, non dovrebbe dare un errore di compilazione a System.out.println(o.count)? Dopotutto, sto provando ad accedere direttamente a una variabile privata.
Il codice funziona anche bene.

+2

Classe MyClass conosce la variabile count, quindi nessun problema – SaintLike

+18

È privato della classe, non dell'istanza. Java non tenta di impedire alla mano sinistra di colpire la mano destra. ;) –

+0

Generare tramite Eclipse o IDEA metodi hashCode e uguali, hanno sempre un aspetto così – Maksym

risposta

56

Un membro privato è accessibile da qualsiasi metodo all'interno della classe in cui è dichiarato, indipendentemente dal fatto che tale metodo acceda al proprio membro privato (this) o al membro privato di un'altra istanza.

Ciò viene affermato nel JLS 6.6.1:

... In caso contrario, se il membro o il costruttore è dichiarato private, quindi l'accesso è consentito se e solo se si verifica all'interno del corpo della classe di livello superiore (§ 7.6) che racchiude la dichiarazione del membro o del costruttore.

Questa caratteristica di Java consente di scrivere i metodi che accettano un'istanza della classe come argomento (per esempio - clone(Object other), compareTo(Object other)) senza fare affidamento sulla classe avere getter non private per tutte le proprietà private che hanno bisogno di accessibile.

+1

TBH, non ero coscientemente consapevole di ciò, ma è elencato esplicitamente come avvertimento per il privato nel tomo Java sulla mia scrivania (Listino 9.6 a pagina 200 in Krüger, Hansen: "Handbuch der Java-Programmierung", Addison -Wesley, 2012). Nessuna menzione a prima vista in "Inside the JAVA Virtual Machine" di Venners, tho. Grazie per la domanda e le risposte. – hiergiltdiestfu

+0

Grazie, ora ha senso. Ho sempre usato 'compareTo' e' equals' con getter. È strano quando ho notato che possiamo accederci senza getter. –

12

I campi privati ​​sono privati ​​per la classe nel suo complesso, non solo per l'oggetto.

Altre classi non sanno che MyClass ha un campo chiamato conteggio; tuttavia, un oggetto MyClass sa che un altro oggetto MyClass ha il campo count.

+0

bella aggiunta e solo la spiegazione che mi serviva –

0

Metodi, variabili e costruttori dichiarati privati ​​sono accessibili solo all'interno della classe dichiarata. Controllare il official documentation

3

Anche se è l'istanza della stessa classe in cui è testPrivate scritto, ma non dovrebbe attraverso un errore di compilazione a System.out.println (o.count);

No. Non genererà mai un errore di compilazione.

Questo è molto simile a ciò che fa un getter e setter semplice o un costruttore di copie. Ricordate possiamo accedere private membri utilizzando this.

public MyClass { 
    private String propertyOne; 
    private String propertyTwo; 

    // cannot access otherObject private members directly 
    // so we use getters 
    // But MyClass private members are accessible using this. 
    public MyClass(OtherClass otherObject) { 
     this.propertyOne = otherObject.getPropertyOne(); 
     this.propertyTwo = otherObject.calculatePropertyTwo(); 
    } 

    public void setPropertyOne(String propertyOne) { 
     this.propertyOne = propertyOne; 
    } 

    public String getPropertyOne() { 
     return this.propertyOne; 
    } 
} 

Il tuo metodo testPrivate accetta un'istanza di MyClass. Poiché testPrivate è un metodo all'interno di MyClass, avrà accesso alle proprietà private.

public void testPrivate(MyClass o) { 
     this.propertyOne = o.propertOne; 
    } 

I metodi definiti all'interno della classe avranno sempre accesso alla sua private membri, attraverso this. e variabile di istanza.

Ma se si definisce testPrivate al di fuori di MyClass, non sarà possibile accedere ai membri private.Lì dovrai usare un metodo o un setter o un getter.

6

Gli accessi non sono sicurezza! Sono incapsulamenti, per impedire agli altri di dover conoscere il codice.

Considerare se qualcuno ha scritto un Quantum Bogo Sort, ma è scomparso una volta che ha annullato l'ultimo bug - la comprensione del codice fa sì che uno sia eliminato dall'universo o impazzire.

Nonostante questo inconveniente minore, se incapsulato correttamente, questo dovrebbe diventare l'algoritmo di ordinamento preferito, poiché tutti i campi e i metodi tranne Sort devono essere privati.

Non sai come funziona e non vuoi sapere come funziona, ma funziona e basta. Se d'altra parte, tutto è pubblico, e devi capire come fa ciò che fa per usarlo correttamente - questo è solo per molto fastidio, mi limiterò a quicksort.

Problemi correlati