/** * The signum of this BigInteger: -1 for negative, 0 for zero, or * 1 for positive. Note that the BigInteger zero <i>must</i> have * a signum of 0. This is necessary to ensures that there is exactly one * representation for each BigInteger value. * * @serial */ finalint signum;
/** * The magnitude of this BigInteger, in <i>big-endian</i> order: the * zeroth element of this array is the most-significant int of the * magnitude. The magnitude must be "minimal" in that the most-significant * int ({@code mag[0]}) must be non-zero. This is necessary to * ensure that there is exactly one representation for each BigInteger * value. Note that this implies that the BigInteger zero has a * zero-length mag array. */ finalint[] mag;
/** * This internal constructor differs from its public cousin * with the arguments reversed in two ways: it assumes that its * arguments are correct, and it doesn't copy the magnitude array. */ BigInteger(int[] magnitude, int signum) { this.signum = (magnitude.length == 0 ? 0 : signum); this.mag = magnitude; if (mag.length >= MAX_MAG_LENGTH) { checkRange(); } }
1 2 3 4 5 6 7 8 9 10
/** * Returns a BigInteger whose value is {@code (-this)}. * * @return {@code -this} */ public BigInteger negate() { returnnewBigInteger(this.mag, -this.signum); }
불변 객체끼리는 내부 데이터를 공유할수 있다.
위에코드는 BigInteger라는 불변객에인데 negate메소드에서 크기는 같고 부호만 반데인 새로운 것을 생성하는데 int[]은 가변이지만 복사하지 않고 공유하는데 그결과 새로만든 인스턴스도 원본 인스턴스가 가르치는 내부 배열을 그대로 가르킨다.
불변객체들을 구성요소로 사용하면 이점이 많다. 아무리 구조가 복잡해도 불변을 유지하기가 편하기 때문이다. Map이나 Set의 키나 원소로 쓰기 좋다 map이나 set의 값이 바뀌면 불변이 깨지는데 그런 걱정을 안해도 된다.
불변객체는 그자체로 실패 원자성(예외가 발생되어도 그객체는 여전히 유효한 상태야 된다.)을 제공한다. 상태가 절대 안변하니 잠깐이라도 불일치 상태에 빠질 가능성이 없다.
불변 클래스에 단점은 값이 다르면 반드시 독립된 객체로 만들어야 된다.
클래스는 특별한 상황이 아니면 불변이여야 된다. 무조건 setter를 만들지는 말자
불변으로 만들수 없는 클래스라도 변경할수 있는 부분을 최소화하자. 다른 합당한 이유가 없다면 모든 필드는 private final이여야 된다.