수색…


소개

변경 불가능 객체는 인스턴스가 초기화 된 후에 변경되지 않는 인스턴스입니다. 예를 들어, String은 변경 불가능한 클래스이며 일단 인스턴스화되면 값은 변경되지 않습니다.

비고

Java의 일부 불변 클래스 :

  1. java.lang.String
  2. 기본 유형의 래퍼 클래스 : java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float
  3. 대부분의 열거 형 클래스는 변경할 수 없지만 사실 구체적인 경우에 따라 다릅니다.
  4. java.math.BigInteger 및 java.math.BigDecimal (적어도 클래스 자체의 객체)
  5. java.io.File. 이것은 VM 외부의 객체 (로컬 시스템의 파일)를 나타냅니다.이 객체는 존재할 수도 있고 존재하지 않을 수도 있으며,이 외부 객체의 상태를 수정하고 쿼리하는 몇 가지 메소드가 있습니다. 그러나 File 객체 자체는 변경되지 않습니다.

불변 클래스를 정의하는 규칙

다음 규칙은 변경 불가능한 객체를 만드는 간단한 전략을 정의합니다.

  1. 필드에 의해 참조 된 필드 또는 객체를 수정하는 메서드 인 "setter"메서드를 제공하지 마십시오.
  2. 모든 필드를 최종적으로 비공개로 만듭니다.
  3. 서브 클래스가 메소드를 오버라이드 (override) 할 수 없게합니다. 가장 간단한 방법은 클래스를 final로 선언하는 것입니다. 보다 정교한 접근법은 생성자를 private으로 만들고 팩토리 메소드로 인스턴스를 생성하는 것입니다.
  4. 인스턴스 필드가 변경 가능한 객체에 대한 참조를 포함하는 경우 해당 객체가 변경되지 않도록하십시오.
  5. 변경 가능한 객체를 수정하는 메소드를 제공하지 마십시오.
  6. 변경 가능한 객체에 대한 참조를 공유하지 마십시오. 생성자에 전달 된 외부의 변경 가능한 객체에 대한 참조를 저장하지 마십시오. 필요한 경우 복사본을 만들고 복사본에 대한 참조를 저장합니다. 마찬가지로, 메서드에서 원본을 반환하지 않도록 내부 수정 가능한 개체의 복사본을 만들어야합니다.

변경 가능한 ref가없는 예

public final class Color {
    final private int red;
    final private int green;
    final private int blue;

    private void check(int red, int green, int blue) {
        if (red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {
            throw new IllegalArgumentException();
        }
    }

    public Color(int red, int green, int blue) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
    }

    public Color invert() {
        return new Color(255 - red, 255 - green, 255 - blue);
    }
}

변경 가능한 ref가있는 예

이 경우 클래스 Point는 변경 가능하며 일부 사용자는이 클래스의 객체 상태를 수정할 수 있습니다.

class Point {
    private int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

//...

public final class ImmutableCircle {
    private final Point center;
    private final double radius;

    public ImmutableCircle(Point center, double radius) {
        // we create new object here because it shouldn't be changed
        this.center = new Point(center.getX(), center.getY());
        this.radius = radius;
    }

불변의 장점은 무엇입니까?

불변의 이점은 동시성에 있습니다. 여러 스레드가 동일한 객체의 상태를 변경하려고 시도 할 수 있기 때문에 변경 가능한 객체에서 정확성을 유지하는 것은 어렵습니다. 일부 객체는 동일한 객체의 다른 상태를보고 스레드에 대한 읽기 및 쓰기의 타이밍에 따라 달라집니다. 목적.

불변 개체를 가짐으로써, 불변 개체의 상태가 변경되지 않기 때문에, 개체를보고있는 모든 스레드가 동일한 상태를 볼 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow