2011-02-26 11 views
11

Yo tenía la impresión de que las variables no estáticas privadas sólo se podía acceder por métodos llamados en el objeto de que las variables residen en, pero este no es el caso. ¿Podría alguien explicar el razonamiento detrás de por qué las siguientes compilaciones y ejecuciones?métodos estáticos Java que acceden variables privadas

public class Sandbox { 
    private String _privateString = "unmodified"; 
    public static void setPrivateString(String str, Sandbox s) { 
     s._privateString = str; 
    } 
    public String toString() 
    { 
     return _privateString; 
    } 

    public static void main(String[] args) { 
     Sandbox s = new Sandbox(); 
     setPrivateString("modified", s); 
     System.out.println(s); 
    } 
} 

de salida:

modified 

EDIT: Lo mismo es cierto en C#.

+0

Puede haber modificado '_privateString' directamente desde' main() 'ya que está en la misma clase. –

Respuesta

17

variables miembro privadas de la clase A se puede acceder (es decir, leer/escrito a) por cualquier método de la clase A (estático o no estática), por lo que en su ejemplo, ya que el método de cambiar la cadena es un método de la misma clase a la que pertenece el miembro, se le concede acceso a la variable.

La razón es porque una clase se considera un cuerpo autónomo de lógica (es decir, una implementación específica), por lo que tiene sentido que la privacidad esté contenida dentro de una clase, aunque no hay ninguna razón para excluir métodos estáticos de ese acceso correcto, ya que ellos también son parte de la implementación específica que proporciona la clase.

+1

Entonces, ¿cualquier instancia de una clase tiene acceso a todas las variables privadas de todas las demás instancias de esa clase? –

+0

¡Exactamente! Lo cual al principio puede parecer extraño, aunque tiene sentido cuando lo piensas en términos de que una clase es una sola implementación. – davin

+0

@ T.K.Por ejemplo, 'public void changeOther (String changeTo, Sandbox s) {s._privateString = changeTo; } 'se puede ejecutar en otra instancia en total:' s1.changeOther ("blah", s2); ' – davin

2

La regla es simple. Los métodos miembros de una clase pueden acceder y modificar miembros privados de la misma clase, independientemente de sus modificadores de visibilidad.

3

Como se ha mencionado en algunos otros mensajes, sistema de visibilidad de Java es decir, no una basada en objetos basado en clases.

Tenga en cuenta que este es utilizado en el compilador: Cuando haya anidado clases y tener acceso a un campo privado de la clase externa, se genera un método estático sintética pública para permitir el acceso. Por lo general, se denomina "acceso $ 0", etc. Puede crear un código de bytes que viole la encaplulación sin Reflection API utilizando estos métodos sintéticos. También puede acceder a ellos desde Reflection API sin habilitar el acceso a miembros privados. Muchas cosas locas se pueden hacer ...

Si no había tal sistema de visibilidad, compilador probablemente tendría que compilarlo elsehow.

... Hoewver, al final programador por lo general no necesitan saber este detalle. Los IDE no incluyen métodos sintéticos en la finalización del código y espero que los compiladores (excepto Jasmin) no permitan su uso. Entonces, si no genera un bytecode y no usa Reflection API e ignora estos métodos en la pila, probablemente no necesite conocer este detalle.

3

usted parece estar confundiendo con visibilityscope. Las variables de instancia están en el ámbito de una instancia, por lo que no se puede acceder directamente en un método estático, sino solo con un calificador de referencia de instancia: s._privateString en su caso.

Sin embargo, esto no significa que las variables de instancia no son visible para un método estático dentro de la misma clase, como private medios visibles dentro de la clase (para cualquier miembro con cualquier ámbito de aplicación).

Cuestiones relacionadas