2011-07-06 4 views
4

final이 아니고 다른 클래스 B가 그것을 확장 할 수 있습니다 (B가 변경 가능). 직렬화로 인해 A의 불변성이 영향을받을 수있는 방법이 있습니까?Java : Immutability and serialization

개체를 serialize하고 프로그램에서 상태를 변경 한 다음이를 역 직렬화하는 작은 프로그램을 작성했습니다. 객체가 직렬화 된 형태로 다시 가져 왔습니다. 그래서 나는 그것을 직렬화함으로써 A의 불변성을 변경할 수있는 방법이 있는지 궁금하다.

답변

5

정확히 무엇을 요구 하느냐에 달려 있습니다. 당신이 넣은 것보다 다른 값을 얻고 싶다면, 직렬화를 통해 할 수 있습니다. serialize 된 데이터는 메모리에있는 A의 인스턴스에서 완전히 분리됩니다. Java가 직렬화 된 데이터에서 오브젝트를 재구성 할 때, 데이터를 작성하는 데 사용 된 A의 원래 인스턴스에 대해서는 알지 못하거나 신경 쓰지 않습니다. 직렬화 된 정보에서 제공되는 청사진을 기반으로 메모리에 데이터 구조를 간단히 구성합니다.

따라서 A을 재구성 할 때 얻은 결과를 수정하려면 이진 직렬화 된 데이터를 수동으로 수정하면됩니다. 그렇게하려면 Java의 직렬화 형식을 잘 이해해야하지만 확실히 할 수 있습니다.

A의 원래 인스턴스를 직렬화를 통해 수정할 수 있는지 묻는다면 (예를 들어, 직렬화를 통해 새 인스턴스를 구성하지 않고도 값이 변경되는 동일한 객체를 얻는 것처럼), 대답 아니오, 할 수 없습니다. 직렬화는 객체의 현재 상태에 대한 스냅 샷을 작성하기 만합니다. 직렬화 해제는 소스 인스턴스에서 완전히 분리 된 새 오브젝트 인스턴스를 작성합니다. 따라서 값을 수동으로 변경할 수도 있지만 새로운 값을 가진 새 객체는 일단 비 직렬화되면 여전히 변경되지 않습니다.

불변 클래스 A의 인스턴스를 직렬화 한 다음 데이터를 A 클래스의 인스턴스로 식별하지만 무언가로 데이터를 deserialize하는 방법이 있는지 묻는다면 대답도 가능합니다. 직렬화 된 데이터는 표현되는 오브젝트의 클래스를 지정하지만 클래스 정의 자체는 직렬화되지 않습니다. 따라서 A의 인스턴스를 직렬화 한 다음 변경 가능한 클래스 B의 인스턴스를 deserialize하도록 A의 변경 가능한 인스턴스를 가져 오는 것과 같지 않도록 지정된 클래스를 변경할 수 있습니다.

2

불변성을 변경할 수 없습니다 (클래스는 여전히 변경 불가능합니다). 그러나 직렬화 된 정보를 편집하여 값을 변경할 수 있습니다.

반영을 통해 변경할 수도 있습니다. 변경 불가능한 것은 마법 보호가 아닙니다. 프로그램 안정성을 향상시키는 뮤 테이터가없는 클래스를 만드는 것입니다. 비록 변수가 아마도 최종 적이어야 할 필요는 없지만, 당신은 모든 메소드에 대해 항상 같은 값을 리턴해야합니다.

어쨌든 변경 불가능한 클래스를 확장하려는 경우에는 확장을 불변으로 변경하는 것이 좋습니다. 실제로 클래스를 확장하지 않을 가능성이 크지 않으면 캡슐화하기를 원할 것입니다 (is-a 관계 또는 has-a가 있습니까?)

0

개체를 serialize 할 때 해당 개체가 변경되지 않거나 변경되지 않습니다.

새 오브젝트의 직렬화를 해제하면 기록 된 정보와 비 직렬화 작업 수행 방법에 따라 첫 번째 오브젝트가 재구성됩니다.

예를 들어 불변 클래스가 있고 필드가 일시적인 경우 역 직렬화 된 사본에는 해당 필드가 설정되지 않습니다 (일시적으로 설정 한 것)