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 foola mise en œuvre de et éventuellement changer fooHelperde 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.
privatepermet aux auteurs de bibliothèque de diviser les bibliothèques en méthodes de taille gérable (et en privateclasses 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 privaten'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 privateJava. Le type de privatecela empêche une classe externe d'accéder aux membres d'une autre classe externe, privatece qui est vérifié par le vérificateur de bytecode, mais aussi les privates 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 Bd'accéder C.id'une manière qui dépasse le vérificateur de bytecode. Malheureusement, puisque ClassLoadervous permet de créer une classe à partir de a byte[], il est assez simple de se rendre chez les particuliers qui Cont exposé aux classes internes en créant une nouvelle classe dansC le package de 's qui est possible si Cle pot de' s n'a pas été scellé.
Une mise en œuvre appropriée privatené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 privatela 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.