java中的类不变吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (27)

我GOOGLE了这个话题,但除了维基百科之外,我没有找到任何其他有用的文档或文章。

任何人都可以用简单的语言向我解释这意味着什么,或者向我介绍一些好的和易于理解的文档?

提问于
用户回答回答于

这并不意味着参考java的任何内容。

类不变只是一个对所有类的实例持有的属性,不管其他代码如何。

例如,

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

X的类不变,有一个y属性,它从来没有null,它有一个类型的值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违规†),因为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中获得更不可靠的东西,您的不变量可能会持续下去,并且系统长期可靠性更高。

用户回答回答于

对于实例类,它们必须是真实的。例如,如果一个类有一个属性X并且不变量可以是X,那么必须大于0.据我所知,没有用于维护不变量的内建方法,您必须使属性保持私有状态并确保您的getter和setter强制执行不变属性。

有注释可用于使用反射和拦截器来检查属性。 http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

扫码关注云+社区