Non significa nulla in particolare in riferimento a java.
Un invariante di classe è semplicemente una proprietà che vale per tutte le istanze di una classe, sempre, non importa quale altro codice faccia.
Per esempio,
class X {
final Y y = new Y();
}
X ha l'invariante di classe che ci sia una proprietà y
e non è mai null
ed ha un valore di tipo Y
.
class Counter {
private int x;
public int count() { return x++; }
}
non riesce a mantenere due invarianti importanti
- Che
count
mai restituisce un valore negativo a causa di possibili underflow.
- Le chiamate a
count
aumentano in modo strettamente monotono.
La classe modificata conserva quei due invarianti.
class Counter {
private int x;
public synchronized int count() {
if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); }
return x++;
}
}
ma non riesce a conservare l'invariante che chiama count
sempre riesce normalmente assenti (TCB violazioni †) perché count
potrebbe un'eccezione o potrebbe bloccare se un thread stallo possiede monitor del contatore.
Ogni lingua con classi facilita il mantenimento di alcuni invarianti di classe ma non di altri. Java non fa eccezione:
- Le classi Java hanno o non hanno proprietà e metodi coerenti, quindi gli invarianti di interfaccia sono facili da mantenere.
- Le classi Java possono proteggere i loro campi
private
, quindi le invarianti che si basano su dati privati sono facili da mantenere.
- Le classi Java possono essere definitive, quindi le invarianti che si basano sul fatto che non esiste un codice che violi un'invarianza creando una sottoclasse dannosa possono essere mantenute.
- Java consente di introdurre i valori
null
in molti modi, quindi è difficile mantenere invarianti "ha un valore reale".
- Java ha thread che significa che le classi che non si sincronizzano hanno problemi a mantenere invarianti che si basano su operazioni sequenziali in un thread che si verificano insieme.
- Java ha delle eccezioni che rendono facile mantenere invarianti come "restituisce un risultato con proprietà p o non restituisce alcun risultato" ma è più difficile mantenere invarianti come "restituisce sempre un risultato".
† - Un esternalità o TCB violazione è un evento che un progettista di sistemi assume ottimisticamente non accadrà.
In genere abbiamo appena fiducia che l'hardware di base funziona come pubblicizzato quando si parla di proprietà dei linguaggi di alto livello costruite su di loro, e le nostre argomentazioni che invarianti detengono non prendere in considerazione la possibilità di:
- Un programmatore che utilizza i hook di debug per modificare le variabili locali mentre un programma viene eseguito in modi che il codice non può eseguire.
- I colleghi non utilizzano la riflessione con
setAccessible
per modificare le tabelle di ricerca private
.
- Loki che modifica la fisica causando il confronto errato del processore tra due numeri.
Per alcuni sistemi nostro TCB potrebbe includere solo le parti del sistema, in modo da non potremmo supporre che
- Un amministratore o un demone privilegiata non uccideranno il nostro processo di JVM,
ma possiamo supporre che
- Possiamo controllare un file system transazionale affidabile.
Il più alto livello di un sistema, maggiore è la sua TCB è tipicamente, ma le cose più inaffidabili che si possono ottenere dalla vostra TCB, più è probabile che i vostri invarianti sono da tenere, e il più affidabile il sistema sarà a lungo termine.
+1 per la domanda perché la pagina di Wikipedia ha un ottimo esempio di qualcosa che non sapevo di poter fare - ha anche degli esempi. La loro spiegazione è meglio di quanto potrei fare per te; è piuttosto semplice. – iandisme
https://www.stanford.edu/~pgbovine/programming-with-rep-invariants.htm –
Se sei interessato a invarianti w.r.t. Java, forse saresti interessato a [contratti per Java] (http://google-opensource.blogspot.com/2011/02/contracts-for-java.html). –