2013-04-17 2 views
2

대학에서 자바 수업을하는 동안 공용 getter가 개인 가변 객체에 대한 참조를 반환하는 개인 정보 유출 개념에 대해 알게되었습니다. 다음과 같이복제 또는 unmodifiableCollection

은 준 예였다

private HashSet<*> priv = new HashSet<*> 

public Collection<*> getPriv() { 
    return this.priv; 
} 

지금이 가진 문제는 이제 객체의 클라이언트 인가 (구문이 없다, 나는 메모리에서 일하고 있어요 확실히 맞다면 용서) 의도적으로 또는 다른 방법으로 개인 HashSet을 손상시킬 수있는 기회. 외부 변경으로부터 보호 객체의 내부 상태가 아니라 때문에,

public Collection<*> getPriv() { 
    return Collections.unmodifiableCollection (this.priv); 
} 

이 나에게 좋은 해결책처럼 보인다 시도를 : 과정에

는, 제안 된 솔루션은 다음 사용하는 것이 었습니다 반환 된 unmodifiableCollection을 수정하면 예외가 트리거됩니다. 그러나이 문제는 컬렉션에서만 작동한다는 것입니다. 다른 변경 가능한 Java 클래스에는 해당하지 않는 것으로 보입니다.

public Collection<*> getPriv() { 
    return this.priv.clone(); 
} 

이 어떤 복제 가능한 개체에서 작동하지만, 반환 된 객체가 클라이언트 객체의 콘텐츠를 수정할 수 있습니다 나는 이후 읽은 자바

대부분의 책은 다음과 같은 제안한다. 객체의 내부 상태는 여전히 보호되어 있지만 실제로 수정할 수없는 데이터를 수정하려고하면 예외가 발생하지 않습니다. 이것은 개인용 컬렉션을 가져 와서 수정하고, 변경 사항이 오브젝트에 반영되지 않은 이유에 대해 신비하게 남겨져있는 실수를 할 수 있음을 의미하므로 다른 클래스에 대한 오류 (개인 상태 수정)를 다른 클래스로 변경했습니다 (변경 불가능한 복제본 수정).

return Collections.unmodifiableCollection (this.priv); 어떤 클래스 (또는 적어도 cloneable 구현과 같은 일부 전제 조건을 충족하는 모든 클래스)에서 작동하는보다 일반적인 방법이 있습니까, 아니면 모든 개인용 버전의 변경 가능하고 변경 불가능한 버전을 구현할 수있는 유일한 방법입니까? 클래스를 통해 getter를 통해 공개적으로 사용 가능하게 할 수 있습니까?

+0

* 그러나 반환 된 개체는 클라이언트 개체의 콘텐츠로 수정할 수 있습니다. * => 이러한 개체가 올바르게 복사되어있는 한 중요한 문제는 아닙니다. – assylias

답변

3

나는 대답이 '예'입니다.

Collections.unmodifiableCollection은보기 만 반환합니다. 기본적으로 컬렉션에는 어댑터 클래스가 포함되어 있으며 Collection을 가져 와서 특정 메서드 호출을 전달합니다. '위험한'메소드의 경우, 대신 예외가 발생합니다. 이것은 당연히 사물을 구현하기 위해 전달 된 기본 컬렉션에 의존합니다. getSize()이 개체를 변경하면 어댑터에서 getSize()을 호출해도 기본 클래스로 전달 된 다음 수정됩니다.

클라이언트로 반환하는 여러 클래스 (또는 인터페이스) 수를 제한하여 작업량을 줄일 수 있습니다. 또한 더 많은 클래스를 기본적으로 불변으로 만들 수 있습니다. 함수형 언어의 공통 패러다임은 훨씬 간단하게 만듭니다. 불행하게도 Java는 불변으로 불필요하게 못생긴 객체로 작업을합니다.

불변의보기를 자동으로 생성하는 것과 같은 가능성이 있지만, 이는 복잡하고 어쨌든 어떤 방법으로 전달할 것인지 결정할 방법이 필요합니다.

마지막으로 setAccessible 등에서 사용자를 보호 할 수 없습니다. 그러나이 경우 의도적으로 표준 VM 제약을 위반하고 있으므로 걱정할 필요가 없습니다.보안에 걱정이된다면 어쨌든 SecurityManager에서 모든 신뢰할 수없는 코드를 실행해야합니다.