I have not been in a situation where a compiler error caused by these keywords would have saved me from a bug.
Non è tanto necessario salvare gli autori delle applicazioni dagli errori, ma lasciare che gli autori delle librerie decidano quali parti della loro implementazione si stanno impegnando a mantenere.
Se ho una libreria
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
Potrei voler sostituire l'implementazione di foo
e possibilmente cambiare fooHelper
in modi radicali. Se un gruppo di persone ha deciso di utilizzare fooHelper
nonostante tutti gli avvisi nella mia documentazione, potrei non riuscire a farlo.
private
consente agli autori di librerie di rompere le librerie in metodi di dimensioni gestibili (e classi di helper private
) senza il timore che saranno costretti a mantenere quei dettagli interni per anni.
What would make it worthwhile for the compiler to enforce information hiding?
Una nota a margine, in Java private
non viene applicata dal compilatore, ma da Java bytecode verifier .
Can reflection override this mechanism? What would make it worthwhile for the compiler to enforce information hiding?
In Java, non solo la riflessione può ignorare questo meccanismo. Esistono due tipi di private
in Java. Il tipo di private
che impedisce ad una classe esterna di accedere ai membri private
di un'altra classe esterna che è controllata dal verificatore bytecode, ma anche private
s che vengono utilizzati da una classe interna tramite un metodo accessor sintetico pacchetto-privato come in
public class C {
private int i = 42;
public class B {
public void incr() { ++i; }
}
}
Poiché la classe B
(in realtà chiamata C$B
) utilizza i
, il compilatore crea un metodo di accesso sintetico che consente a B
di accedere a C.i
in modo da superare il verificatore bytecode. Sfortunatamente, dal momento che ClassLoader
ti permette di creare una classe da un byte[]
, è abbastanza semplice arrivare ai privati che C
ha esposto a classi interne creando una nuova classe nel pacchetto di C
che è possibile se il barattolo di C
non è stato sigillato.
Un'appropriata implementazione private
richiede il coordinamento tra i classloader, il verificatore di codice byte e il criterio di sicurezza che può impedire l'accesso riflessivo ai dati privati.
Can it be used to secure a class' secret state from being attacked?
Sì. "La scomposizione sicura" è possibile quando i programmatori possono collaborare mantenendo ciascuno le proprietà di sicurezza dei loro moduli - Non devo fidarmi dell'autore di un altro modulo di codice per non violare le proprietà di sicurezza del mio modulo.
Lingue delle capacità degli oggetti come Joe-E usa il nascondiglio delle informazioni e altri mezzi per rendere possibile la decomposizione sicura:
Joe-E is a subset of the Java programming language designed to support secure programming according to object-capability discipline. Joe-E is intended to facilitate construction of secure systems, as well as to facilitate security reviews of systems built in Joe-E.
Il documento collegato da quella pagina fornisce un esempio di come l'imposizione di private
rende possibile la decomposizione sicura.
Providing secure encapsulation.
Figure 1. An append-only logging facility.
public final class Log {
private final StringBuilder content;
public Log() {
content = new StringBuilder();
}
public void write(String s) {
content.append(s);
}
}
Consider Fig. 1, which illustrates how one might build an append-only log facility.
Provided that the rest of the program is written in Joe-E,
a code reviewer can be confident that log entries can only
be added, and cannot be modified or removed. This review
is practical because it requires only inspection of the Log
class, and does not require review of any other code. Consequently, verifying this property requires only local reasoning about the logging code.