Question

L'accès privé au membre niveau de la classe ou au niveau de l'objet. Si elle est au niveau de l'objet, le code suivant ne doit pas compiler

    class PrivateMember {
   private int i;
   public PrivateMember() {
      i = 2;
   }
   public void printI() {
      System.out.println("i is: "+i);
   }
   public void messWithI(PrivateMember t) {
      t.i *= 2;
   }
   public static void main (String args[]) {
      PrivateMember sub = new PrivateMember();
      PrivateMember obj = new PrivateMember();
      obj.printI();
      sub.messWithI(obj);
      obj.printI();
   }
}

S'il vous plaît préciser si l'accès à l'élément i de obj dans la méthode messWithI () du sous-marin est valide

Était-ce utile?

La solution

Comme DevSolar a dit, il est au niveau de la classe (niveau supérieur).

De article 6.6 de la spécification du langage Java :

  

Dans le cas contraire, si le membre ou   constructeur est déclarée privée, puis   l'accès est autorisé si et seulement si elle   se produit dans le corps de la partie supérieure   classe de niveau (§7.6) qui entoure la   déclaration du membre ou   constructeur.

Notez qu'il n'y a pas d'indication qu'il est réservé aux membres d'un objet particulier.

de Java 7, le compilateur ne permet plus l'accès aux membres privés des variables de type . Donc, si la méthode avait une signature comme il serait alors public <T extends PrivateMember> void messWithI(T t) une erreur du compilateur pour accéder t.i. Cela ne changerait pas votre scénario particulier, cependant.

Autres conseils

Notez que vous ne même pas besoin d'un accès au niveau source au mess avec des champs privés. En utilisant java.lang.reflect.AccessibleObject.setAccessibe(), tout le code peut accéder à tous les membres privés de tout autre code, sauf si vous spécifiez une politique de sécurité qui interdit il.

private est pas en soi une fonction de sécurité! Il est simplement un signal fort aux autres développeurs que quelque chose est un détail de mise en œuvre interne que d'autres parties du code ne doit pas dépendre.

Ni. Accès privé est scope à la classe de fermeture de haut niveau, afin que vous puissiez accéder aux membres privés de classe différente dans la même classe de haut niveau:

class PrivateAccess {
    static class InnerOne {
        private int value;
    }

    static class InnerTwo {
        int getOne ( InnerOne other ) {
            return other.value;
        }
    }
}

Le sens habituel d'accès de classe signifie que vous avez accès à d'autres instances privates du même type. En Java, un accès privé est déterminé lexicalement, et non par type.

niveau de classe. L'idée est que le code d'une classe (mais rien d'autre) sait comment manipuler des objets de cette classe.

Si vous avez accès au code source de la classe de toute façon, il y a peu de sens dans « cacher » quoi que ce soit de vous.

Comme d'autres l'ont dit, privé, accès par défaut ( « private package »), protégé et peut-être dans le module JDK 7 sont de la classe en fonction (il y a des règles très étranges pour les classes imbriquées héritage que je peux » me souviens pas). Mais pourquoi?

Au départ, il est en bas à des méthodes qui agissent comme opérateurs binaires (ou plus). Pour la mise en œuvre efficace dont ils ont besoin souvent ou sont plus faciles à écrire sans avoir à utiliser ou modifier l'API publique. Jeter un œil sur les mises en œuvre de equals - dans un bon code, vous trouverez un accès direct des champs avec quelques appels de méthode this. (L'aspect de la performance de c'est maintenant la plupart du temps hors de propos avec JVMs modernes inline appels communs, mais la question de la qualité du code est toujours là.)

Il suffit d'ajouter à la réponse de DevSolar, je me attends messWithI à déclarer statique en tant que tel:

public static void messWithI(PrivateMember t) {
  t.i *= 2;

} J'ai eu du mal à lire, même ce qu'il est que vous essayez de faire sans l'indication « statique » ... Et il est également plus facile de répondre à votre question initiale - qui est que les membres privés ne sont pas limités dans leur portée juste l'instance en question.

La même page dit, dans la sous-section 6.6.8, vous pouvez également trouver la déclaration suivante:

  

Un membre de la classe privée ou d'un constructeur est accessible uniquement dans le corps de la classe de niveau supérieur qui entoure la déclaration du membre ou constructeur. Il n'est pas héritée par les sous-classes.

Le membre de la classe privée dont l'accès nous évaluons ici est i .

messWithI public void () est une méthode qui existe dans le corps de la classe de niveau supérieur où i a été déclarée, ce qui est, précisément, PrivateMember .

Votre construction répond à la déclaration ci-dessus, et qui est la raison pour laquelle il fonctionne sans problème.

Thas est une autre façon de dire la même chose que Jon et Devsolar.

Les modificateurs d'accès pour les membres de la classe sont liés à l'endroit où le code est écrit (dans lequel paquet, et dans quelle classe), peu importe le type de membre l'accès se voit accorder:. Un membre de la classe ou un membre de l'instance

Logiquement, vous ne pouvez pas utiliser un membre d'instance d'une classe si vous ne disposez pas d'une instance de la classe, mais qui est un autre problème, lié au cycle de vie du membre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top