什么是java中的类不变量?

时间:2012-01-17 22:00:07

标签: java terminology invariants

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

任何人都可以用简单的语言向我解释它的含义或者向我推荐一些简单易懂的文档吗?

3 个答案:

答案 0 :(得分:77)

对于java来说,这并不意味着什么。

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

例如,

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的调用严格单调增加。
  3. 修改后的类保留了这两个不变量。

    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返回结果或不返回结果”,但更难维护“始终返回结果”等不变量。

    7. † - 外部性 TCB违规是系统设计人员乐观地认为不会发生的事件。

      通常我们只相信基本硬件在讨论构建在它们上面的高级语言的属性时就像宣传的那样工作,而不变量持有的参数不考虑以下可能性:

      • 程序员使用调试挂钩来改变局部变量,因为程序以代码不能运行的方式运行。
      • 您的同行不会使用setAccessible的反射来修改private查找表。
      • Loki改变物理原因导致处理器错误地比较两个数字。

      对于某些系统,我们的TCB可能只包含系统的一部分,因此我们可能不会假设

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

      但我们可以假设

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

      更高级别的系统,其TCB通常越大,但是从TCB中获得的事物越不可靠,您的不变量就越有可能持有,并且您的系统在更长时间内越可靠运行

答案 1 :(得分:13)

不变意味着无论发生什么变化或使用/转换它的人都应该坚持自己的条件。也就是说,即使在通过使用公共方法进行转换之后,类的属性总是满足或满足某些条件。因此,确保该类及其属性的该类的客户端或用户。

例如,

    函数参数的
  1. 条件是,它应该始终是> 0(大于零)或不应为空。
  2. 帐号类的minimum_account_balance属性说明,它不能低于100.因此所有公共函数都应该遵守这个条件并确保类不变。
  3. 基于规则的变量之间的依赖关系,即一个变量的值取决于另一个变量,因此如果一个变量,使用一些fix-rule,其他变量也必须改变。必须保留2个变量之间的关系。如果没有,则违反不变量。

答案 2 :(得分:9)

它们是关于实例类必须是真实的事实。例如,如果一个类具有属性X且不变,则X必须大于0.据我所知,没有用于维护不变量的内置方法,必须使属性为私有,并确保getter和setter强制执行不变属性。

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