2011-10-27 9 views
9

me encontré con la siguiente característica "extraña" hoy - si tiene una referencia a un objeto de la clase A en el cuerpo de la clase A se puede acceder a los campos privados de este objeto - es decir:Acceso de campo privado de Java posible al tener una referencia?

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

¿Alguien tiene una buena explicación sobre esto?

+2

Esta característica es bastante útil cuando tiene que escribir un método 'iguales'. –

+2

La misma pregunta que: http://stackoverflow.com/questions/2126984/why-is-the-access-to-a-private-field-not-forbidden, http://stackoverflow.com/questions/4340129/accessing -private-field-in-java, http://stackoverflow.com/questions/312168/java-private-field-visibility –

Respuesta

19

Los modificadores de acceso funcionan en el nivel de clase, no en el nivel de instancia: todos los códigos en la misma clase pueden acceder a miembros privados de todas las instancias de la clase.

Nada particularmente extraño al respecto.

3

Como f() es miembro de Foo, tiene el privilegio de acceder a los miembros privados de Foo. No es una sorpresa para mí.

+0

Por eso podemos acceder a foo.bar cuando foo es otra instancia de la clase y barra de Foo es un campo privado – asenovm

+1

@iLate: Porque así se especifica el idioma ... –

+0

@iLate: Supongo que los diseñadores simplemente siguieron el comportamiento de C++. – LLS

0

Porque privado no significa que es privado desde el exterior del objeto, sino privado de otras clases. Estás dentro de Foo, por lo tanto, puedes ver el bar.

De esa manera hacer constructores privados trabajan en Singleton etc.

0

Esas palabras clave están orientadas de clase, no orientado a objetos. Así que solo mira y ve "oh eh, un objeto de clase Foo está tratando de acceder a un objeto privado en Foo. Bueno, está bien".

5

Está destinado a ser de esta manera.

Citando la Java Language Specification:

Un miembro (clase, interfaz, un campo o método) de una referencia (clase, interfaz o array), escriba o un constructor de un tipo de clase es accesible sólo si el tipo es accesible y el miembro o constructor se declara para permitir el acceso:

  • ...
  • (de lo contrario,) si el miembro o constructor se declara privada, se podrá acceder si y sólo si se produce dentro el cuerpo del nivel superior cla ss (§7.6) que encierra la declaración del miembro.
  • ...
+2

+1 para la referencia JLS. –

1

Tiene sentido si se tiene en cuenta la intención del modificador 'privado' para ocultar los detalles de implementación.

Trate de pensar en términos de "esto debe ser privado para esta clase" (que en Java equivale a "esto debe ser privado para este archivo fuente") en lugar de "esto debería ser privado para esta instancia".

0

@Michael La respuesta es correcta. El comportamiento es el mismo para .NET para el código @asenovm.

Además, es lo mismo para las clases internas como para Java. Aunque defina una variable como privada, puede acceder a ella. Me sorprendí cuando me encontré al principio porque es diferente para 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 
    } 
} 

Esto no es lo mismo para C# clases anidadas. Si pegas este código en Visual Studio, no funciona. El compilador se molesta por los niveles de acceso.

Cuestiones relacionadas