什么是Java中的类不变式?

我搜索了该主题,但是除了Wikipedia之外,我没有找到任何其他有用的文档或文章。

有人可以用简单的词向我解释这意味着什么,还是可以使我参考一些易于理解的好文档?

回答:

对于Java而言,这并不意味着什么。

类不变式只是一个属性,它始终为一个类的所有实例保存,无论其他代码做什么。

例如,

class X {

final Y y = new Y();

}

X具有不变的类,即存在一个y属性,并且永远不存在,null并且它具有type值Y

class Counter {

private int x;

public int count() { return x++; }

}

无法保持两个重要的不变式

  1. count永远不会返回,因为可能下溢负值。
  2. 要求count严格单调增加。

修改后的类保留了这两个不变式。

class Counter {

private int x;

public synchronized int count() {

if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); }

return x++;

}

}

但无法保留count始终正常成功调用的不变式(缺少TCB-violations

†),因为count如果死锁线程拥有计数器的监视器,它可能会引发异常或阻塞。

每种带有类的语言都易于维护某些类不变式,而不能维护其他不变式。Java也不例外:

  1. Java类始终具有或不具有属性和方法,因此接口不变式易于维护。
  2. Java类可以保护其private字段,因此依赖私有数据的不变量易于维护。
  3. Java类可以是最终的,因此可以维护不依赖通过编写恶意子类来违反不变量的代码的不变量。
  4. Java允许null值以多种方式潜行,因此很难维护“具有真实值”的不变式。
  5. Java具有线程,这意味着不同步的类很难维护依赖于同时发生的线程中顺序操作的不变式。
  6. Java有一些异常,可以轻松维护诸如“返回带有属性p的结果或不返回结果”之类的不变量,而维护诸如“始终返回结果”之类的不变性则更加困难。


†- 外部性违反TCB

是系统设计人员乐观地认为不会发生的事件。

通常,我们只相信基本硬件能够像在其上构建的高级语言的属性那样进行宣传,而我们不变式的论点并未考虑以下可能性:

  • 当程序运行时,使用调试钩子来更改局部变量的程序员以代码无法运行的方式运行。
  • 您的对等方不使用反射setAccessible来修改private查找表。
  • Loki改变物理结构会导致处理器错误地比较两个数字。

对于某些系统,我们的TCB可能仅包括系统的一部分,因此我们可能不会假定

  • 管理员或特权守护程序不会终止我们的JVM进程,

但是我们可以假设

  • 我们可以检查点到可靠的事务性文件系统。

系统级别越高,通常其TCB越大,但是从TCB中获得的不可靠信息越多,不变量保持的可能性就越大,从长远来看,系统越可靠。

以上是 什么是Java中的类不变式? 的全部内容, 来源链接: utcz.com/qa/416081.html

回到顶部