[java] Java에서 클래스 불변이란 무엇입니까?

주제를 검색했지만 위키피디아 외에는 유용한 문서 나 기사를 찾지 못했습니다.

아무도 그것이 의미하는 바를 간단한 말로 설명하거나 멋지고 이해하기 쉬운 문서를 참조 할 수 있습니까?



답변

Java와 관련하여 특별히 의미하는 것은 아닙니다.

클래스 불변은 다른 코드가 수행하는 작업에 관계없이 항상 클래스의 모든 인스턴스를 유지하는 속성입니다.

예를 들면

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

X는 y속성이 있고 결코 존재하지 않으며 nulltype 값을 갖는다 는 불변 클래스를 가지고 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에서 얻을 수있는 불안정한 항목이 많을수록 불변성이 유지 될 가능성이 높아지고 장기적으로 시스템의 안정성이 높아집니다.


답변

Invariant는 변경 사항이나 사용 / 변형에 관계없이 조건을 고수해야하는 것을 의미합니다. 즉, 클래스의 속성은 public 메서드를 사용하여 변형을 거친 후에도 항상 어떤 조건을 충족하거나 만족시킨다. 따라서이 클래스의 클라이언트 또는 사용자는 클래스 및 해당 속성에 대해 보장됩니다.

예를 들면

  1. 함수 인수의 조건은 항상> 0 (0보다 큼)이거나 null이 아니어야한다는 것입니다.
  2. 계정 클래스의 minimum_account_balance 속성은 100 이하로 내려갈 수 없습니다. 따라서 모든 공용 함수는이 조건을 존중하고 클래스 불변성을 보장해야합니다.
  3. 변수 간의 규칙 기반 종속성, 즉 한 변수의 값이 다른 변수에 종속되므로 하나가 변경되면 일부 수정 규칙을 사용하여 다른 변수도 변경되어야합니다. 두 변수 간의이 관계는 유지되어야합니다. 그렇지 않으면 불변이 위반됩니다.


답변

인스턴스 클래스에 대해 사실이어야하는 사실입니다. 예를 들어 클래스에 X 속성이 있고 불변이 X는 0보다 커야합니다. 내 지식으로는 속성을 비공개로 설정하고 getter와 setter가 불변 속성을 적용하는지 확인해야합니다.

리플렉션과 인터셉터를 사용하여 속성을 확인할 수있는 주석이 있습니다.
http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html


답변