2013-09-05 1 views
4

변경 가능한 List 멤버가 있어도 다음 클래스를 변경하지 못하게하려고합니다. 이것을 어떻게 할 수 있습니까?변경할 수있는 멤버가 있어도이 클래스를 변경하지 못하게하려면 어떻게해야합니까?

class MyImmutableClass { 
     private List<Integer> data; 
     public MyImmutableClass(List<Integer> data) { 
      this.data = data; 
     } 
     public List<Integer> getData() { 
      return data; 
     } 
    } 

다음은 객체 상태를 수정하는 main() 함수의 테스트 클래스입니다.

class TestMyImmutableClass{ 
    public static void main(String[] args) { 
     List<Integer> data = new ArrayList<Integer>(); 
     data.add(2); 
     data.add(5); 
     MyImmutableClass obj = new MyImmutableClass(data); 
     obj.getData().add(3); 
     System.out.println("Data is; " + obj.getData()); 
    } 
} 

O/P : 대신에 대한 참조를 반환 Data is; [2, 5, 3] 당신에

+0

테스트 케이스를 완전히 이해하지 못했습니다. 클래스가 불변 인 경우 3을 추가 할 수 없습니다. – user949300

+0

또한 멤버 변수에'final'을 추가하십시오. –

+0

당신은 @MadProgrammer로부터 훌륭한 답변을 얻었지만, 앞으로 도움이 될 것입니다 : http://mutabilitydetector.org. 클래스 테스트가 불변인지 확인하기 위해 단위 테스트를 작성하고이를 수정하는 방법을 안내합니다. 면책 조항 : 나는 그것을 썼다 : – Grundlefleck

답변

2

Eclipse Collections을 사용하는 경우 MyImmutableClass.data의 유형을 ImmutableList으로 변경할 수 있습니다.

class MyImmutableClass { 
    private ImmutableList<Integer> data; 
    public MyImmutableClass(List<Integer> data) { 
     this.data = Lists.immutable.withAll(data); 
    } 
    public ListIterable<Integer> getData() { 
     return data; 
    } 
} 

이클립스 컬렉션의 ImmutableListListIterable 유형은 add()remove() 방법이없는 즉, 계약 불변입니다. 리턴 된리스트 getData()에서 반환 된리스트를 변경할 수 없다는 것이 확실합니다. 두 ImmutableListMutableList

ListIterable 그래서 당신이 API를 변경하지 않고 변경 불가능한리스트에 ImmutableList에서 구현을 변경할 수 있습니다 확장합니다.

class MyImmutableClass { 
    private MutableList<Integer> data; 
    public MyImmutableClass(List<Integer> data) { 
     this.data = Lists.mutable.withAll(data); 
    } 
    public ListIterable<Integer> getData() { 
     return data.asUnmodifiable(); 
    } 
} 

참고 : 나는 이클립스 모음에 대한 커미터입니다.

7

getData 방법 당신의 List 같은 ...

public List<Integer> getData() { 
    return data; 
} 

당신은 변경 불가능한 List 대신

반환 할 수
public List<Integer> getData() { 
    return Collections.unmodifiableList(data); 
} 

당신은 또한 원래 목록의 복사본을 만들어야합니다,

바와 같이 user949300 지적 업데이트 ... 자세한 내용은 Collections.unmodifiableList를 참조하십시오.

public MyImmutableClass(List<Integer> data) { 
    this.data = new ArrayList<Integer>(data); 
} 

이렇게하면 원래 목록에 액세스 할 수있는 사람이 수정할 수 없게됩니다. 당신의 생성자에서

+1

-1 죄송합니다. 목록을 전달한 발신자가 목록을 수정할 수 있으므로이 사람을 보내야합니다.내 대답을 보라. – user949300

+1

@ user949300 +1 매우 좋은 지적입니다. 지금 업데이트되었습니다. – MadProgrammer

+0

좋아, downvote를 취소합니다 ... – user949300

6

, 완전성 및 명확성을 위해

this.data = Collections.unmodifiableList(new ArrayList(data));

final로 데이터 필드를 선언합니다.

관련 문제