2010-12-15 6 views
6

나는 일반적으로 추상 클래스가 Java로 Serializable 될 수 없다는 것을 읽었다. 서브 클래스는 직렬화 가능해야합니다 (예를 들어, 추상 클래스에 필드가있는 경우 사용자 정의 읽기, 쓰기 메소드가 필요할 경우).Java에서 추상 클래스를 직렬화하지 않는 이유는 무엇입니까?

이유가 무엇입니까? 왜 나쁜 디자인으로 간주됩니까?

업데이트 1 : 일부 필드와 세 개의 하위 클래스가있는 추상 클래스가 있습니다. 현재로서는 다음 접근 방식을 사용하고 있습니다.

모든 하위 클래스를 사용자 정의 읽기, 쓰기 메소드로 직렬화 할 수 있습니다. 추상 클래스에는 다음과 같은 메소드가 있습니다.

void writeFields(ObjectOutputStream out)throws IOException { .... } 

void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... } 

하위 클래스의 사용자 정의 읽기, 쓰기 메소드에서이 메소드를 호출하여 추상 클래스의 필드를 직렬화합니다. 이 접근법이 맞습니까? 아니면 다른 더 좋은 접근법이 있습니까?

업데이트 2 : 나는 Tom의 조언을 받아 내 추상 클래스 Serializable을 만들었습니다. (나는 모든 서브 클래스를 Serializable로하고 추상적 인 클래스의 데이터를 가지고있다.) 이것은 제쳐두고 사용하는 이야기를 완성하기 위해서이다. reflection to change final fields as advised by Jeremy Manson.

+0

이 질문은 모든 객체 지향 언어에 적용됩니다. –

답변

1

필자는 반드시 나쁜 설계라는 것을 모른다. 직렬화는 효과적으로 구현 문제입니다 (Josh Bloch는 나와 의견이 맞지 않습니다.) 따라서 인터페이스에는 이해가 가지 않습니다. 추상 클래스에 상태가 있으면 직렬화 할 수 있도록하려고합니다. 그것이 국가를 가지고 있지 않다면 그렇게 할 이유가 없습니다.

예를 들어 보겠습니다. java.security.cert.Certificate"type" serialisable 필드가있는 추상 직렬 가능 클래스입니다. 직렬화 가능하지 않은 경우, 서브 클래스가 직렬화되어 그 필드를 설정할 수 없게됩니다. 당신은 해킹을 강요 당할 것입니다.

java.io.Serializable은 해킹입니다. 그것은 인터페이스가되어서는 안됩니다. 주석 (또는 transient과 같은 언어 진화)이 더 적절했을 것입니다.

항상 그렇듯이 컴포지션을 상속으로 지정하고 임의의 클래스를 직렬화 할 수 없게하는 것이 가장 좋습니다.

+0

업데이트 된 질문을 참조하십시오. – athena

+0

@athena 당신은 실제로 API에서 그런 메소드를 원하지 않습니다. –

+0

왜 안 되니? 나는 모든 하위 클래스를 Serializable으로하고 싶다. 추상 클래스에는 필드가 있습니다. 이 상황에서, (사용자 정의 읽기 쓰기 메소드를 사용하여) 추상 클래스를 Serializable로 만드는 것이 더 나은가? – athena

3

oposite 위치를 취한다. 객체를 직렬화 해제하려면 해당 유형이 무엇입니까?

정의에 따라 추상 클래스는 인스턴스화 할 수 없습니다. 그것을 직렬화 할 수 있다면 직렬화 될 수도 있고 추상 클래스의 인스턴스를 얻을 수도 있다는 것을 의미합니다. 이는 추상 클래스의 정의와 모순되며 따라서 수행 될 수 없습니다.

+0

+1, 똑같은 말을 조금씩 다르게하려고했지만 답은 내가 말했던 것보다 훨씬 간결하게 설명됩니다. –

+3

오브젝트를 직렬화 복원 한 경우, 클래스는 직렬화 된 오브젝트와 같을 것입니다 ('writeReplace' /'readResolve'를주고받습니다). –

+1

나는 귀하의 주장에 결함이 있다고 생각합니다. 추상 클래스를 인스턴스화하는 것은 불가능합니다. 따라서 astract 클래스의 역 직렬화가 필요하지는 않습니다. 추상 클래스의 역 직렬화는 파생 된 구체적인 클래스의 컨텍스트에서 수행됩니다. 즉, 클래스는 역 직렬화 시점에서 알려져 있습니다. – DwB

5

왜냐하면 Abstract 클래스가 Serializable을 구현하는 경우 하위 유형이 Serializable이 아니어야한다고 말할 수있는 방법이 없다고 생각합니다. 각각의 구체적인 유형을 선언하는 것이 더 좋음 ...

+0

+1. collections API는 그 좋은 예입니다. – Bozho

+0

나는 모든 하위 클래스를 Serializable로하고 싶다. 추상 클래스에는 필드가 있습니다. 이 경우, 추상 클래스를 Serializable로 만드는 것이 더 좋습니까? – athena

+0

컬렉션 프레임 워크를보고 있습니다 - 아니요;) AbstractList는 직렬화 할 수 없습니다. 하지만 어쨌든 큰 차이는 아닙니다. – Bozho

0

강제 결정이기 때문에 잘못된 디자인 일뿐입니다. 직렬화 할 수없는 멤버가있는 하위 클래스를 원한다면 어떻게할까요?

그게 이유입니다.

예. 목록은 Serializable이 아니지만 모든 주요 목록 구현은 다음과 같습니다.(목록은 인터페이스지만, 멤버가없는 추상 클래스 =/= 인터페이스)

관련 문제