它并不意味着任何特别参考java。
类不变量只是一个属性,它保存一个类的所有实例,总是,无论其他代码是什么。
例如,
class X {
final Y y = new Y();
}
X具有类不变性,即存在y属性,并且它永远不为空,并且其值为类型Y.
class Counter {
private int x;
public int count() { return x++; }
}
不能保持两个重要的不变量
>该计数从不返回负值,因为可能出现下溢。
>调用count是严格单调增加。
修改后的类保留这两个不变量。
class Counter {
private int x;
public synchronized int count() {
if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); }
return x++;
}
}
但不能保留调用计数总是正常成功的不变量(不存在TCB违规†),因为计数可能会抛出异常,或者如果死锁线程拥有计数器的监视器,它可能会阻塞。
每个具有类的语言使得容易维护一些类不变式而不是其他类。 Java也不例外:
> Java类始终具有或不具有属性和方法,因此接口不变式易于维护。
> Java类可以保护其私有字段,因此依赖私有数据的不变式很容易维护。
> Java类可以是最终的,因此依赖于不存在通过制作恶意子类违反不变量的代码的不变量可以被维护。
> Java允许空值在许多方面潜行,所以很难保持“有一个真正的价值”不变量。
> Java具有线程,这意味着不同步的类在维护不变量方面有困难,依赖于在一起发生的线程中的顺序操作。
> Java具有异常,它使得易于维护不变量,例如“返回具有属性p的结果或返回无结果”,但更难以维护不变量,如“总是返回结果”。
† – 外部性或TCB违规是系统设计者乐观地假定不会发生的事件。
通常我们只是相信基本的硬件工作像广告时谈论的高级语言的属性建立在它们,我们的不变量持有的参数不考虑以下的可能性:
>程序员使用调试钩子来改变局部变量,因为程序以代码不能运行的方式运行。
>您的对等体不使用带setAccessible的反射来修改私有查找表。
> Loki改变物理学使处理器不正确地比较两个数字。
对于一些系统,我们的TCB可能只包括系统的一部分,所以我们可能不会假设
>管理员或特权守护程序不会杀死我们的JVM进程,
但我们可以假设
>我们可以检查点到一个可靠的事务文件系统。
较高级别的系统,其TCB通常较大,但是您可以从TCB中获得的不可靠的事情越多,您的不变式就越可能保持,并且从长远来看,您的系统将更可靠。