2011-02-26 4 views
11

J'avais l'impression que l'accès aux variables privées non statiques ne pouvait se faire que par des méthodes appelées sur l'objet dans lequel résident les variables, mais ce n'est pas le cas. Quelqu'un pourrait-il s'il vous plaît expliquer le raisonnement derrière pourquoi compile et fonctionne?Méthodes statiques Java accédant aux variables privées

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); 
    } 
} 

Sortie:

modified 

EDIT: en est de même en C#.

+0

Vous pourriez avoir modifié '_privateString' directement à partir de' main() 'comme étant dans la même classe. –

Répondre

17

Les variables de membre privées de la classe A sont accessibles (c.-à-lire/écrit) par n'importe quelle méthode de classe A (statique ou non statique), donc dans votre exemple, puisque la méthode changeant la chaîne est une méthode de la même classe que le membre appartient, il est accordé l'accès à la variable. La raison en est qu'une classe est considérée comme un corps de logique autonome (c'est-à-dire une implémentation spécifique), il est donc logique que la confidentialité soit contenue dans une classe, bien qu'il n'y ait aucune raison d'exclure les méthodes statiques de cet accès. à droite, puisqu'ils font aussi partie de la mise en œuvre spécifique que la classe fournit.

+1

Ainsi, une instance d'une classe a accès à toutes les variables privées de toutes les autres instances de cette classe? –

+0

Exactement! Ce qui d'abord peut sembler étrange, bien que cela ait du sens quand on y pense en termes de classe étant une seule implémentation. – davin

+0

@ T.K.Ainsi, par exemple, 'public void changeOther (Chaîne changeTo, Sandbox s) {s._privateString = changeTo; } 'peut être exécuté sur une autre instance:' s1.changeOther ("blah", s2); ' – davin

2

La règle est simple. Les méthodes membres d'une classe peuvent accéder et modifier des membres privés de la même classe, quels que soient leurs modificateurs de visibilité.

3

Comme mentionné dans d'autres articles, le système de visibilité de Java est basé sur les classes, et non sur les objets.

Notez que cela est utilisé dans le compilateur: Lorsque vous avez des classes imbriquées et que vous accédez à un champ privé de la classe externe, une méthode statique synthétique publique est générée pour autoriser l'accès. Il est généralement nommé "access $ 0" etc. Vous pouvez créer un bytecode qui viole l'encaplulation sans l'API Reflection en utilisant ces méthodes synthétiques. Vous pouvez également y accéder à partir de l'API Reflection sans autoriser l'accès aux membres privés. Beaucoup de choses folles peuvent être faites ...

S'il n'y avait pas un tel système de visibilité, le compilateur aurait probablement besoin de le compiler autrement.

... Hoewver, le programmeur final n'a généralement pas besoin de connaître ce détail. Les IDE n'incluent pas les méthodes synthétiques dans la complétion de code et j'espère que les compilateurs (sauf Jasmin) ne vous permettent pas de l'utiliser. Donc, si vous ne générez pas de bytecode et n'utilisez pas l'API Reflection et que vous ignorez ces méthodes dans la pile, vous n'avez probablement pas besoin de connaître ce détail.

3

Vous semblez confondre visibility avec scope. Les variables d'instance sont dans la portée d'une instance, elles ne peuvent donc pas être accédées directement dans une méthode statique, mais seulement avec un qualificateur de référence d'instance: s._privateString dans votre cas.

Toutefois, cela ne signifie pas que les variables d'instance ne sont pas visibles pour une méthode statique à l'intérieur de la même classe, comme private signifie visible à l'intérieur de la classe (pour tout membre de l'une quelconque champ d'application).

Questions connexes