Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a class invariant in Java?

I googled the topic, but besides Wikipedia I didn't find any further useful documentation or articles.

Can anybody explain to me in simple words what it means or refer me to some nice and easy to understand documentation?

like image 550
Saurabh Kumar Avatar asked Jan 17 '12 22:01

Saurabh Kumar


People also ask

What is an invariant example?

Examples. A simple example of invariance is expressed in our ability to count. For a finite set of objects of any kind, there is a number to which we always arrive, regardless of the order in which we count the objects in the set.

What is type invariant?

In computer programming, specifically object-oriented programming, a class invariant (or type invariant) is an invariant used for constraining objects of a class. Methods of the class should preserve the invariant. The class invariant constrains the state stored in the object.

What does invariant mean in programming?

An invariant is a condition or relation that is always true. The definition is modified somewhat for concurrent execution: an invariant is a condition or relation that is true when the associated lock is being set. Once the lock is set, the invariant can be false.

What is an invariant and why is it useful?

An invariant is a statement (one hopes well-founded) that will always be true whenever it applies, and is not represented in the code itself. Invariants are indeed useful for proving correctness, but they are not limited to that case. They are also useful for defensive-programming and during debugging.


2 Answers

It doesn't mean anything in particular in reference to Java.

A class invariant is simply a property that holds for all instances of a class, always, no matter what other code does.

For example,

class X {   final Y y = new Y(); } 

X has the class invariant that there is a y property and it is never null and it has a value of type Y.

class Counter {   private int x;    public int count() { return x++; } } 

This fails to maintain two important invariants:

  1. That count never returns a negative value because of possible underflow.
  2. That calls to count are strictly monotonically increasing.

The modified class preserves those two invariants.

class Counter {   private int x;    public synchronized int count() {     if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); }     return x++;   } } 

...but fails to preserve the invariant that calls to count always succeed normally (absent TCB-violations) because count might throw an exception or it might block if a deadlocked thread owns the counter's monitor.

Each language with classes make it easy to maintain some class invariants but not others. Java is no exception:

  1. Java classes consistently have or do not have properties and methods, so interface invariants are easy to maintain.
  2. Java classes can protect their private fields, so invariants that rely on private data are easy to maintain.
  3. Java classes can be final, so invariants that rely on there being no code that violates an invariant by crafting a malicious subclass can be maintained.
  4. Java allows null values to sneak in in many ways, so it is tough to maintain "has a real value" invariants.
  5. Java has threads which means that classes that do not synchronize have trouble maintaining invariants that rely on sequential operations in a thread happening together.
  6. Java has exceptions which makes it easy to maintain invariants like "returns a result with property p or returns no result" but harder to maintain invariants like "always returns a result".

† - An externality or TCB violation is an event which a systems designer optimistically assumes will not happen.

Typically we just trust that the basic hardware works as advertised when talking about properties of high-level languages built on them, and our arguments that invariants hold don't take into account the possibility of:

  • A programmer using debug hooks to alter local variables as a program runs in ways that code cannot.
  • Your peers don't use reflection with setAccessible to modify private lookup tables.
  • Loki altering physics causing your processor to incorrectly compare two numbers.

For some systems our TCB might include only parts of the system, so we might not assume that

  • An administrator or privileged daemon won't kill our JVM process,

...but we might assume that:

  • We can checkpoint to a reliable transactional file-system.

The higher-level a system, the larger its TCB typically is, but the more unreliable things you can get out of your TCB, the more likely your invariants are to hold, and the more reliable your system will be in the long run.

like image 90
Mike Samuel Avatar answered Sep 30 '22 22:09

Mike Samuel


Invariant means something that should stick to its conditions no matter whatever changes or whoever uses/transforms it. That is to say, a property of a class always fulfills or satisfies some condition even after going through transformations by using public methods. So, the client or user of this class is ensured about the class and its property.

For example,

  1. Condition on a function argument is that, it should always be > 0 (greater than zero) or should not be null.
  2. Minimum_account_balance property of an account class states, it cannot go below 100. So all public functions should respect this condition and ensure class invariant.
  3. Rule based dependency between variables, that is, the value of one variable depends on another, so if one changes, using some fix-rule, the other must also change. This relationship between 2 variables must be preserved. If it does not, then invariant is violated.
like image 38
aab10 Avatar answered Sep 30 '22 22:09

aab10