Подтвердить что ты не робот

Что такое инвариант класса в java?

Я искал тему, но кроме Wikipedia Я не нашел никакой дополнительной полезной документации или статей.

Может кто-нибудь объяснить мне простыми словами, что это значит или передать мне какую-нибудь красивую и понятную документацию?

4b9b3361

Ответ 1

Это не означает ничего, особенно в отношении java.

Инвариант класса - это просто свойство, которое выполняется для всех экземпляров класса, всегда, независимо от того, что делает другой код.

Например,

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

X имеет инвариант к классу, что существует свойство y, и он никогда не null и имеет значение типа y.

class Counter {
  private int x;

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

не удается сохранить два важных инварианта

  • count никогда не возвращает отрицательное значение из-за возможного недополнения.
  • То, что вызывает count, строго монотонно возрастает.

Измененный класс сохраняет эти два инварианта.

class Counter {
  private int x;

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

но не сохраняет инвариант, который вызывает count, всегда преуспевает нормально (отсутствуют TCB-нарушения ), потому что count может генерировать исключение или блокировать, если заторможенный поток владеет монитор счетчика.

Каждый язык с классами упрощает сохранение некоторых инвариантов класса, но не других. Java не является исключением:

  • Классы Java последовательно имеют или не имеют свойств и методов, поэтому интерфейсные инварианты просты в обслуживании.
  • Классы Java могут защитить свои поля private, поэтому инварианты, которые полагаются на личные данные, легко поддерживать.
  • Java-классы могут быть окончательными, поэтому можно поддерживать инварианты, которые полагаются на отсутствие кода, который нарушает инвариант, создавая вредоносный подкласс.
  • Java позволяет использовать значения null во многих отношениях, поэтому трудно поддерживать инварианты "имеет реальное значение".
  • Java имеет потоки, что означает, что классы, которые не синхронизируются, имеют проблемы с сохранением инвариантов, которые полагаются на последовательные операции в потоке, происходящем вместе.
  • У Java есть исключения, которые упрощают сохранение таких инвариантов, как "возвращает результат с помощью свойства p или не возвращает результат", но сложнее поддерживать такие инварианты, как "всегда возвращает результат".

† - Внешность или Нарушение правил TCB - это событие, которое оптимистически предполагает системный дизайнер, не произойдет.

Обычно мы просто верим, что основное оборудование работает так, как рекламируется, когда речь идет о свойствах высокоуровневых языков, построенных на них, и наши аргументы, которые сохраняются инвариантами, не учитывают возможность:

  • Программист, использующий отладочные перехватчики для изменения локальных переменных в качестве программы, работает таким образом, что код не может.
  • Ваши коллеги не используют отражение с помощью setAccessible для изменения таблиц поиска private.
  • Loki меняет физику, заставляя ваш процессор неправильно сравнивать два числа.

Для некоторых систем наш TCB может включать только части системы, поэтому мы можем не предполагать, что

  • Администратор или привилегированный демон не убьет наш JVM-процесс,

но мы можем предположить, что

  • Мы можем поставить контрольную точку в надежную транзакционную файловую систему.

Система более высокого уровня, чем больше ее TCB, тем более ненадежные вещи, которые вы можете получить из своего TCB, тем вероятнее, что ваши инварианты будут удерживаться, и чем более надежной будет ваша система в долгосрочной перспективе работать.

Ответ 2

Это факты, которые должны быть верны в отношении класса экземпляра. Например, если класс имеет свойство X, а инвариант может быть X, то он должен быть больше 0. Насколько я знаю, нет встроенного метода для сохранения инвариантов, вы должны сделать свойства частными и убедиться, что ваши геттеры и сеттеры обеспечивают свойство инвариантности.

Существуют доступные аннотации, которые могут проверять свойства с использованием отражения и перехватчиков. http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

Ответ 3

Инвариант означает то, что должно придерживаться его условий независимо от того, что изменится, или того, кто его использует/трансформирует. Иными словами, свойство класса всегда удовлетворяет или удовлетворяет некоторому условию даже после прохождения преобразований с использованием общедоступных методов. Таким образом, клиент или пользователь этого класса обеспечивается в отношении класса и его свойства.

Например,

  • Условие аргумента функции состоит в том, что оно всегда должно быть > 0 (больше нуля) или не должно быть нулевым.
  • minimum_account_balance свойство состояний учетной записи, оно не может опускаться ниже 100. Таким образом, все публичные функции должны уважать это условие и обеспечивать инвариант класса.
  • зависимость от переменных между переменными, то есть значение одной переменной зависит от другой, поэтому, если кто-то изменяет, используя какое-то правило исправления, другое должно также измениться. Эта связь между двумя переменными должна быть сохранена. Если это не так, то инвариант нарушается.