Je n'ai pas été dans une situation où une erreur de compilation générée par ces mots clés m'aurait sauvé d'un bug.
Il ne s'agit pas tant de sauver les auteurs d'applications des bogues que de laisser les auteurs de bibliothèques décider quelles parties de leur implémentation ils s'engagent à maintenir.
Si j'ai une bibliothèque
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
Je veux peut-être pouvoir remplacer foo
la mise en œuvre de et éventuellement changer fooHelper
de façon radicale. Si un tas de gens ont décidé d'utiliserfooHelper
malgré tous les avertissements dans ma documentation, je ne pourrai peut-être pas le faire.
private
permet aux auteurs de bibliothèque de diviser les bibliothèques en méthodes de taille gérable (et en private
classes d'assistance) sans craindre d'être obligés de conserver ces détails internes pendant des années.
Qu'est-ce qui en vaut la peine pour le compilateur d'appliquer la dissimulation d'informations?
Par ailleurs, en Java private
n'est pas appliqué par le compilateur, mais par le vérificateur de bytecode Java .
La réflexion peut-elle passer outre ce mécanisme? Qu'est-ce qui en vaut la peine pour le compilateur d'appliquer la dissimulation d'informations?
En Java, non seulement la réflexion peut remplacer ce mécanisme. Il existe deux types de private
Java. Le type de private
cela empêche une classe externe d'accéder aux membres d'une autre classe externe, private
ce qui est vérifié par le vérificateur de bytecode, mais aussi les private
s qui sont utilisés par une classe interne via une méthode d'accesseur synthétique package-private comme dans
public class C {
private int i = 42;
public class B {
public void incr() { ++i; }
}
}
Puisque la classe B
(vraiment nommée C$B
) utilise i
, le compilateur crée une méthode d'accesseur synthétique qui permet B
d'accéder C.i
d'une manière qui dépasse le vérificateur de bytecode. Malheureusement, puisque ClassLoader
vous permet de créer une classe à partir de a byte[]
, il est assez simple de se rendre chez les particuliers qui C
ont exposé aux classes internes en créant une nouvelle classe dansC
le package de 's qui est possible si C
le pot de' s n'a pas été scellé.
Une mise en œuvre appropriée private
nécessite une coordination entre les chargeurs de classe, le vérificateur de bytecode et la politique de sécurité, ce qui peut empêcher l'accès réfléchi aux utilisateurs privés.
Peut-il être utilisé pour empêcher un état secret d'une classe d'être attaqué?
Oui. La "décomposition sécurisée" est possible lorsque les programmeurs peuvent collaborer tout en préservant chacun les propriétés de sécurité de leurs modules - je n'ai pas à faire confiance à l'auteur d'un autre module de code pour ne pas violer les propriétés de sécurité de mon module.
Les langages de capacités d'objet comme Joe-E utilisent le masquage d'informations et d'autres moyens pour rendre possible une décomposition sécurisée:
Joe-E est un sous-ensemble du langage de programmation Java conçu pour prendre en charge la programmation sécurisée selon la discipline de capacité objet. Joe-E est destiné à faciliter la construction de systèmes sécurisés, ainsi qu'à faciliter les examens de sécurité des systèmes construits dans Joe-E.
Le document lié à partir de cette page donne un exemple de la façon dont private
la mise en œuvre rend possible une décomposition sécurisée.
Fournir une encapsulation sécurisée.
Figure 1. Une fonction de journalisation en annexe uniquement.
public final class Log {
private final StringBuilder content;
public Log() {
content = new StringBuilder();
}
public void write(String s) {
content.append(s);
}
}
Considérez la figure 1, qui illustre la façon dont on peut créer une fonction de journal avec ajout uniquement. À condition que le reste du programme soit écrit en Joe-E, un réviseur de code peut être sûr que les entrées de journal ne peuvent être ajoutées, et ne peuvent pas être modifiées ou supprimées. Cette révision est pratique car elle ne nécessite qu'une inspection de la Log
classe et ne nécessite la révision d'aucun autre code. Par conséquent, la vérification de cette propriété nécessite uniquement un raisonnement local sur le code de journalisation.