2011-10-27 13 views
9

mi sono imbattuto nel seguente funzione di "strano" di oggi - se si dispone di un riferimento a un oggetto dalla classe A nel corpo della classe A è possibile accedere ai campi privati ​​di questo oggetto - vale a dire:È possibile l'accesso al campo privato Java quando si ha un riferimento?

public class Foo{ 
    private int bar; 
    private Foo foo; 
    public void f() 
    { 
     if(foo.bar == bar) // foo.bar is visible here?! 
     { 
      // 
     } 
    } 
} 

Qualcuno ha una buona spiegazione a riguardo?

+2

Questa funzione è molto utile quando si deve scrivere un metodo 'equals'. –

+2

La stessa domanda di: http://stackoverflow.com/questions/2126984/why-is-the-access-to-a-private-field-not-forbidden, http://stackoverflow.com/questions/4340129/accessibility -private-field-in-java, http://stackoverflow.com/questions/312168/java-private-field-visibility –

risposta

19

I modificatori di accesso funzionano a livello di classe, non a livello di istanza: tutto il codice nella stessa classe può accedere ai membri privati ​​di tutte le istanze della classe.

Niente di particolarmente strano.

3

Poiché f() è un membro di Foo, ha il privilegio di accedere ai membri privati ​​di Foo. Non è una sorpresa per me.

+0

il motivo è perché possiamo accedere a foo.bar quando foo è un'altra istanza della classe Foo e barra è un campo privato – asenovm

+1

@iLate: Perché è così che viene specificata la lingua ... –

+0

@iLate: Credo che i progettisti abbiano appena seguito il comportamento del C++. – LLS

0

Perché privato non significa privato dall'esterno dell'oggetto ma privato da altre classi. Sei all'interno di Foo, quindi puoi vedere la barra.

In questo modo fanno i costruttori privati ​​lavorano in Singletons ecc

0

tali parole chiave sono di classe-oriented, non orientato agli oggetti. Quindi guarda e vede "oh huh, un oggetto della classe Foo sta cercando di accedere a un oggetto privato su Foo. Beh, va bene".

5

È destinato a essere in questo modo.

Citando il Java Language Specification:

Un utente (classe, interfaccia, un campo o metodo) di un riferimento (classe, interfaccia, o array) tipo o un costruttore di un tipo di classe è accessibile solo se il tipo è accessibile e il membro o il costruttore è dichiarato per consentire l'accesso:

  • ...
  • (In caso contrario,) se il membro o il costruttore è dichiarato privato, l'accesso è consentito se e solo se si verifica all'interno il corpo del livello superiore cla ss (§7.6) che racchiude la dichiarazione del membro.
  • ...
+2

+1 per il riferimento JLS. –

1

Ha senso se si considera l'intenzione del modificatore 'privato' per nascondere i dettagli implementativi.

Provate a pensare in termini di "questo dovrebbe essere privato per questa classe" (che in Java equivale a "questo dovrebbe essere privato per questo file sorgente") piuttosto che "questo dovrebbe essere privato di questa istanza".

0

@Michael La risposta è corretta. Il comportamento è lo stesso per .NET per il codice @asenovm.

Inoltre, lo stesso vale per le classi interne anche per Java. Anche se definisci una variabile come privata, puoi accedervi. Ho sorpreso quando ho incontrato in un primo momento perché è diverso per C#.

public class WrapperClass 
{ 

    public static class NotThreadsafe { 
     private int x = 0; 
     //....   
    } 

    public static void main(String[] args) {   
    final NotThreadsafe nts=new NotThreadsafe(); 
    int x = nts.x ; // !!! THIS IS ACCESSIBLE AS WELL FOR JAVA BUT NOT.NET 
    } 
} 

Questo non è lo stesso per le classi nidificate C#. Se si incolla questo codice in Visual Studio non funziona. Il compilatore dà fastidio per i livelli di accesso.

Problemi correlati