JavaTM Platform
Standard Ed. 6

java.io
인터페이스 Serializable

기존의 서브 인터페이스의 일람:
AdapterActivator , Attribute , Attribute , Attributes , BindingIterator , ClientRequestInfo , ClientRequestInterceptor , Codec , CodecFactory , Control , Current , Current , Current , CustomValue , DataInputStream , DataOutputStream , Descriptor , DHPrivateKey , DHPublicKey , DocAttribute , DomainManager , DSAPrivateKey , DSAPublicKey , DynAny , DynAnyFactory , DynArray , DynEnum , DynFixed , DynSequence , DynStruct , DynUnion , DynValue , DynValueBox , DynValueCommon , ECPrivateKey , ECPublicKey , ExtendedRequest , ExtendedResponse , Externalizable , IdAssignmentPolicy , IDLEntity , IDLType , IdUniquenessPolicy , ImplicitActivationPolicy , Interceptor , IORInfo , IORInterceptor , IORInterceptor_3_0 , IRObject , Key , LifespanPolicy , Name , NamingContext , NamingContextExt , NotificationFilter , ObjectReferenceFactory , ObjectReferenceTemplate , ORBInitializer , ORBInitInfo , PBEKey , POA , POAManager , Policy , PolicyFactory , PrintJobAttribute , PrintRequestAttribute , PrintServiceAttribute , PrivateKey , PublicKey , QueryExp , RelationType , RemoteRef , RequestInfo , RequestProcessingPolicy , RSAMultiPrimePrivateCrtKey , RSAPrivateCrtKey , RSAPrivateKey , RSAPublicKey , RunTime , SecretKey , ServantActivator , ServantLocator , ServantManager , ServantRetentionPolicy , ServerRef , ServerRequestInfo , ServerRequestInterceptor , StreamableValue , SupportedValuesAttribute , ThreadPolicy , UnsolicitedNotification , ValueBase , ValueExp


public interface Serializable

클래스의 직렬화 가능성은, java.io.Serializable 인터페이스를 구현하는 클래스에 의해 유효하게 됩니다. 이 인터페이스를 구현하고 있지 않는 클래스에서는, 그 상태가 직렬화 또는 직렬화 복원될 것은 없습니다. 직렬화 가능 클래스의 subtype은, 모두 그 자체가 직렬화 가능합니다. 직렬화 인터페이스는 메소드 또는 필드가 없고, 직렬화 가능하다라고 말하는 의미를 식별하는 기능만을 갖추고 있습니다.

비직렬화 가능 클래스의 subtype을 직렬화 가능하게 하기 위해서, 슈퍼타입의 public 필드, protected 필드, 및 액세스 가능한 경우는 package 필드 상태를 보존 및 복원하는 역할을 subtype이 담당할 수가 있습니다. 다만, subtype이 이 역할을 담당할 수가 있는 것은, subtype에 의해 확장되는 클래스에, 클래스 상태를 초기화하기 위한 인수 없음의 액세스 가능한 생성자 이 있는 경우만입니다. 그렇지 않은 경우에 직렬화 가능 클래스를 선언하면(자) 에러가 됩니다. 에러는 실행시에 검출됩니다.

직렬화 복원때는, 비직렬화 가능 클래스의 필드는, 그 클래스의 public 또는 protected 의 인수 없음의 생성자 을 사용해 초기화됩니다. 인수 없음의 생성자 은, 직렬화 가능 서브 클래스로부터 액세스 가능하지 않으면 안됩니다. 직렬화 가능 서브 클래스의 필드는, 스트림로부터 복원됩니다.

그래프의 순회중에, 직렬화 가능 인터페이스를 지원하고 있지 않는 객체에 조우하는 일이 있습니다. 이 경우는, NotSerializableException 가 throw 되어 이 예외에 의해 비직렬화 가능 객체의 클래스가 특정됩니다.

직렬화와 직렬화 복원 시에 특수한 취급이 필요한 클래스에서는, 정확하게 다음과 같은 시그니챠를 가지는 특수한 메소드를 구현할 필요가 있습니다.

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData() 
     throws ObjectStreamException;
 

writeObject 메소드는, 그 특정의 클래스의 객체 상태를 기입해, 대응하는 readObject 메소드가 객체 상태를 복원할 수 있도록(듯이) 하는 역할을 담당합니다. out.defaultWriteObject 를 호출하는 것에 의해, 객체의 필드를 보존하기 위한 디폴트의 기구를 호출할 수가 있습니다. 이 메소드는, 그 슈퍼 클래스나 서브 클래스에 속하는 상태에 관여할 필요는 없습니다. 상태를 보존하려면 , writeObject 메소드를 사용해 개개의 필드를 ObjectOutputStream 에 기입하는지, 또는 DataOutput 가 지원하는 기본 데이터형용의 메소드를 사용합니다.

readObject 메소드는, 스트림로부터의 read와 클래스 필드의 복원을 실시하는 역할을 담당합니다. 이 메소드는, in.defaultReadObject 메소드를 호출해, 객체의 비 static 필드 및 비 transient 필드를 복원하기 위한 디폴트의 기구를 호출할 수가 있습니다. defaultReadObject 메소드는, 스트림의 정보를 사용해, 현재의 객체내에서 대응하도록(듯이) 지정된 필드와 함께, 스트림에 보존되고 있는 객체의 필드를 할당합니다. 이것으로, 새로운 필드를 추가할 수 있도록(듯이) 클래스가 확장되는 케이스가 처리됩니다. 이 메소드는, 그 슈퍼 클래스나 서브 클래스에 속하는 상태에 관여할 필요는 없습니다. 상태를 보존하려면 , writeObject 메소드를 사용해 개개의 필드를 ObjectOutputStream 에 기입하는지, 또는 DataOutput 가 지원하는 기본 데이터형용의 메소드를 사용합니다.

readObjectNoData 메소드는, 어느 클래스가 직렬화 복원되는 객체의 슈퍼 클래스로서 직렬화 스트림로 지정되어 있지 않을 때에, 그 클래스에 도착해 그 객체 상태를 초기화합니다. 이것은, 수취하는 측이, 보내 옆과는 다른 버젼의 직렬화 복원된 인스턴스의 클래스를 사용해, 수취하는 측의 버젼이 보내 옆의 버젼에 의해 상속되지 않는 클래스를 상속하는 경우에 발생할 가능성이 있습니다. 또, 직렬화 스트림이 개편되었을 경우에도 발생하는 일이 있습니다. 따라서, readObjectNoData 는, 「악의가 있다」또는 부정한 소스 스트림이어도, 직렬화 복원된 객체를 올바르게 초기화하는데 도움이 됩니다.

스트림에 객체를 기입할 때 사용하는 대체 객체를 지정할 필요가 있는 직렬화 가능 클래스에서는, 다음의 시그니챠를 정확하게 지정해, 이 특별한 메소드를 구현할 필요가 있습니다.

 ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
 

이 writeReplace 메소드가 직렬화에 의해 불려 가는 것은, 존재하고 있어, 게다가 직렬화 되는 객체의 클래스내에서 정의되고 있는 메소드로부터 액세스 가능한 경우입니다. 그 때문에, 이 메소드에서는, private, protected, 및 package-private 로 액세스 할 수가 있습니다. 이 메소드에 대한 서브 클래스의 액세스는, java 의 액세스 가능성 규칙에 준거합니다.

대체 객체의 인스턴스를 스트림로부터 읽어들일 때 그 객체를 지정할 필요가 있는 클래스에서는, 다음의 시그니챠를 정확하게 지정해, 이 특별한 메소드를 구현할 필요가 있습니다.

 ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
 

이 readResolve 메소드는, writeReplace 와 같은 호출해 규칙과 액세스 가능성 규칙에 준거합니다.

직렬화 런타임은, 각 직렬화 가능 클래스에 버젼 번호 serialVersionUID 를 관련짓습니다. 이것은, 직렬화 복원중에, 직렬화 객체의 송신측과 수신측이, 직렬화에 관해서 호환성이 있는 객체의 클래스를 로드했는지의 여부를 확인하기 위해서 사용됩니다. 대응하는 송신측의 클래스와는 다른 serialVersionUID 를 가지는 객체의 클래스를 수신측이 로드했을 경우, 직렬화 복원에서는 InvalidClassException 가 발생합니다. 필드명 "serialVersionUID" 를 선언하는 것에 의해, 직렬화 가능 클래스는 독자적인 serialVersionUID 를 명시적으로 선언할 수 있습니다. 이 필드명은, 다음과 같이 static, final, 및 long 형이 아니면 안됩니다.

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
 
직렬화 가능 클래스가 serialVersionUID 를 명시적으로 선언하지 않는 경우, 직렬화 런타임은 「Java(TM) 객체 직렬화 스펙」으로 설명되고 있도록(듯이), 클래스의 다양한 측면에 근거해, 클래스의 serialVersionUID 의 디폴트 값를 계산합니다. 다만, 모든 직렬화 가능 클래스가 serialVersionUID 치를 명시적으로 선언하는 것을 강하게 추천합니다. 이것은, 디폴트의 serialVersionUID 의 계산이, 컴파일러의 구현에 따라서 다를 가능성이 있는 클래스의 상세하게 극히 영향을 받기 쉽고, 직렬화 복원중에 예기치 않은 InvalidClassException 가 발생할 가능성이 있기 (위해)때문에입니다. 따라서, java 컴파일러의 구현이 달라도 serialVersionUID 치의 일관성을 확보로 하려면 , 직렬화 가능 클래스가 serialVersionUID 치를 명시적으로 선언하지 않으면 안됩니다. 또, serialVersionUID 의 명시적인 선언에서는 private 수식자를 사용하는 것을 강하게 추천합니다. 이러한 선언은 직접적으로 선언하는 클래스에게만 적용되기 (위해)때문에입니다. 즉, serialVersionUID 필드는 상속되는 멤버와 같이 사용하기 쉽게 없습니다. 배열 클래스는 serialVersionUID 를 명시적으로 선언할 수 없기 때문에, 항상 디폴트의 계산치를 가집니다만, 배열 클래스에 관해서는 serialVersionUID 치의 일치 요건은 적용되지 않습니다.

도입된 버젼:
JDK1. 1
관련 항목:
ObjectOutputStream , ObjectInputStream , ObjectOutput , ObjectInput , Externalizable


JavaTM Platform
Standard Ed. 6

버그의 보고와 기능의 요청
한층 더 자세한 API 레퍼런스 및 개발자 문서에 대해서는,Java SE 개발자용 문서를 참조해 주세요. 개발자전용의 상세한 해설, 개념의 개요, 용어의 정의, 버그의 회피책, 및 코드 실례가 포함되어 있습니다.

Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms . Documentation Redistribution Policy 도 참조해 주세요.