Ich bin nicht in einer Situation gewesen, in der ein durch diese Schlüsselwörter verursachter Compilerfehler mich vor einem Fehler bewahrt hätte.
Es ist nicht so sehr wichtig, Anwendungsautoren vor Fehlern zu bewahren, sondern vielmehr, dass Bibliotheksautoren entscheiden, welche Teile ihrer Implementierung sie warten möchten.
Wenn ich eine Bibliothek habe
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
Ich möchte vielleicht in der Lage sein, die foo
Implementierung zu ersetzen und möglicherweise fooHelper
auf radikale Weise zu ändern . Wenn sich einige Leute dazu entschlossen haben, fooHelper
trotz aller Warnungen in meiner Dokumentation zu verwenden, kann ich das möglicherweise nicht.
private
Ermöglicht es Bibliotheksautoren, Bibliotheken in überschaubare Methoden (und private
Hilfsklassen) zu unterteilen, ohne befürchten zu müssen, dass sie diese internen Details über Jahre hinweg beibehalten müssen.
Was würde es für den Compiler lohnen, das Verbergen von Informationen zu erzwingen?
In Java private
wird dies nicht vom Compiler, sondern vom Java- Bytecode-Verifizierer erzwungen .
Kann Reflexion diesen Mechanismus außer Kraft setzen? Was würde es für den Compiler lohnen, das Verbergen von Informationen zu erzwingen?
In Java kann nicht nur die Reflexion diesen Mechanismus außer Kraft setzen. private
In Java gibt es zwei Arten . Auf private
diese Weise wird verhindert, dass eine äußere Klasse auf die private
Mitglieder einer anderen äußeren Klasse zugreift, was vom Bytecode-Verifizierer überprüft wird, aber auch auf private
diejenigen, die von einer inneren Klasse über eine paketprivate synthetische Zugriffsmethode wie in verwendet werden
public class C {
private int i = 42;
public class B {
public void incr() { ++i; }
}
}
Da die Klasse B
(mit wirklichem Namen C$B
) verwendet wird i
, erstellt der Compiler eine synthetische B
Zugriffsmethode , die den Zugriff C.i
auf eine Weise ermöglicht, die über den Bytecode-Verifizierer hinausgeht. Da ClassLoader
Sie mit a eine Klasse erstellen können , ist es leider byte[]
ziemlich einfach, auf die Privaten zuzugreifen, C
die inneren Klassen ausgesetzt waren, indem Sie eine neue Klasse in C
s Paket erstellen. Dies ist möglich, wenn C
s Jar nicht versiegelt wurde.
Die ordnungsgemäße private
Durchsetzung erfordert eine Koordinierung zwischen den Klassenladeprogrammen, der Bytecode-Überprüfung und der Sicherheitsrichtlinie, die den reflektierten Zugriff auf Private verhindern kann.
Kann es verwendet werden, um den geheimen Zustand einer Klasse vor Angriffen zu schützen?
Ja. "Sichere Dekomposition" ist möglich, wenn Programmierer zusammenarbeiten können, während die Sicherheitseigenschaften ihrer Module erhalten bleiben. Ich muss dem Autor eines anderen Codemoduls nicht vertrauen, um die Sicherheitseigenschaften meines Moduls nicht zu verletzen.
Object Capabilities-Sprachen wie Joe-E verwenden das Ausblenden von Informationen und andere Mittel, um eine sichere Zerlegung zu ermöglichen:
Joe-E ist eine Teilmenge der Java-Programmiersprache, die zur Unterstützung der sicheren Programmierung gemäß der Objektfähigkeitsdisziplin entwickelt wurde. Joe-E soll den Aufbau sicherer Systeme sowie die Sicherheitsüberprüfung von in Joe-E eingebauten Systemen erleichtern.
Das auf dieser Seite verlinkte Dokument gibt ein Beispiel dafür, wie die private
Durchsetzung eine sichere Zerlegung ermöglicht.
Bereitstellung einer sicheren Kapselung.
Abbildung 1. Eine reine Append-Protokollierungsfunktion.
public final class Log {
private final StringBuilder content;
public Log() {
content = new StringBuilder();
}
public void write(String s) {
content.append(s);
}
}
Betrachten Sie Abb. 1, die veranschaulicht, wie eine reine Append-Protokollfunktion erstellt werden kann. Vorausgesetzt, der Rest des Programms ist in Joe-E geschrieben, kann ein Code-Reviewer davon ausgehen, dass Protokolleinträge nur hinzugefügt und nicht geändert oder entfernt werden können. Diese Überprüfung ist praktisch, da nur eine Überprüfung der Log
Klasse erforderlich ist und kein anderer Code überprüft werden muss. Für die Überprüfung dieser Eigenschaft sind daher nur lokale Überlegungen zum Protokollierungscode erforderlich.