2009-08-24 2 views
18

생성 된 serialVersionUID의 직렬화 된 Java 객체를 확인하는 방법이 있습니까?직렬화 된 객체의 serialVersionUID 찾기

문제는 내가 명시 적으로 serialVersionUID을 지정하지 않고 개체를 직렬화했다는 것입니다. 이제 deserialization 프로세스는 클래스 비 호환성에 대해 불평합니다. 그러나 나는 그것을 양립 할 수없는 방식으로 수업을 바꾸지 않았다. 따라서 객체 데이터에 저장 될 때 클래스에 serialVersionUID을 지정하는 것만으로 충분하다고 가정합니다. 이렇게하려면 serialize 된 데이터에서 serialVersionUID을 읽어야합니다.

+0

메소드가 클래스에 추가되는 경우 어떻게됩니까? 수정 된 직렬화 된 클래스를 사용하여 이전 직렬화 된 객체를 읽을 수 있습니까? – sprezzatura

+0

메소드는 객체의 상태를 구성하지 않으므로 serialVersionUID를 사용하지 않는 한 직렬화 된 객체를 읽는 데 아무런 문제가 없습니다. –

답변

0

정확히 무엇을해야합니까? 자신의 static final long serialVersionUID을 지정하십시오.

문서에 Serializable에 대한 섹션이 있습니다.

serialVersionUID을 지정하지 않으면 @WMR에서 제시 한대로 스트림을 해독하는 것 이외의 다른 방법으로 쉽게 얻을 수 있다고 생각하지 않습니다.

장 참조 6.4이 사용 http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.html

에, 당신은 당신의 직렬화 된 객체의 SerialVersionUID를을 결정할 수 있어야한다 :

+0

serialVersionUID (serialversionuid가 아닌 - Java는 대소 문자를 구분 함)라는 이름을 지정해야합니다. 비공개 정적 final long이어야합니다.) – Jesper

+0

동의합니다. 하지만 직렬화 된 데이터에서 생성 된 uid를 읽을 수있는 방법이 있습니까? – paweloque

1

는 지정된 객체의 직렬화 문법이있다. 나는이 방법에 의해 반환 된 기술자를 대체하여 모든 직렬화 된 데이터를 읽을 수있을 것이라고 생각

public class PrintUIDs extends ObjectInputStream { 

    public PrintUIDs(InputStream in) throws IOException { 
    super(in); 
    } 

    @Override 
    protected ObjectStreamClass readClassDescriptor() throws IOException, 
     ClassNotFoundException { 
    ObjectStreamClass descriptor = super.readClassDescriptor(); 
    System.out.println("name=" + descriptor.getName()); 
    System.out.println("serialVersionUID=" + descriptor.getSerialVersionUID()); 
    return descriptor; 
    } 

    public static void main(String[] args) throws IOException, 
     ClassNotFoundException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(baos); 
    List<Object> list = Arrays.asList((Object) new Date(), UUID.randomUUID()); 
    oos.writeObject(list); 
    oos.close(); 
    InputStream in = new ByteArrayInputStream(baos.toByteArray()); 
    ObjectInputStream ois = new PrintUIDs(in); 
    ois.readObject(); 
    } 

} 

을,하지만 난 그것을 시도하지 않은 :

5

직렬화 된 비트와 연결된 메타 데이터가 있습니다 (원하는 경우 헤더). 어떤 위치에 있는지 알면 메타 데이터의 값을 읽을 수 있습니다 (SerialVersionUID이 클래스 이름과 같은 다른 정보와 함께 기록됩니다).

이 기사가 도움이 될 것이라고 생각합니다 : The Java serialization algorithm revealed.

비트가 명시 적으로 (스트림을 명시 적으로 암호화하지 않는 한) 쓰여지므로 HEX 편집기가 SerialVersionUID이 무엇인지 알아야 할 수도 있습니다.

21

당신이

import java.io.Serializable; 

public class TestSerializable implements Serializable { 

} 

serialversionUID-을 언급 잊어 버린하는 클래스가 있다고 가정 집단 별

의 serialVersionUID의를 찾을 수있는 쉬운 방법이 바로 this-

serialver -classpath . TestSerializable 

이 인쇄물 -

static final long serialVersionUID = 5832063776451490808L; 
long serialVersionUID = ObjectStreamClass.lookup(YourObject.getClass()).getSerialVersionUID(); 

가 너무 당신을 도움이되기를 바랍니다 : 23,516,

하는 serialver는 JDK

이 나를 위해 작동
+2

그러나 이것은 이전 버전의 TestSerializable이있는 경우에만 작동합니다. lewap의 문제는 serialVersionUID의 값이 직렬화 된 객체의 클래스의 이전 버전과 어떤 관련이 있는지 알지 못한다는 것입니다. 그가 더 이상 구버전을 가지지 않아도된다면, 그는 serialver를 사용하여 알아낼 수 없습니다. – Jesper

+0

그게 버전 컨트롤을위한 것입니다. – james

13

와 함께 제공되는 유틸리티입니다.

0

직렬화 된 객체의의 serialVersionUID를 얻을 훨씬 간단한 방법이있다 - 다만 다른 직렬 버전 UID와 같은 클래스에 아파치 평민 직렬화 유틸로 직렬화하고있을 것입니다 예외 메시지를 읽을 수는 더 많거나 적은 :

org.apache.commons.lang.SerializationException : java.io.InvalidClassException : my.example.SerializableClass; 지역 클래스 호환되지 않는 : 스트림 classdesc의 serialVersionUID = -1, 지역 클래스의 serialVersionUID = -2

안드로이드 개발자를위한
0

enter image description here , 당신은 또한 설정에서 직렬화 검사를 활성화 할 수 있습니다

-> 편집기 -> 검사가 -> 사용 "serialVersionUID '확인'이없는 Serializable 클래스, 그리고 나서 Alt + Enter를 누르면 스튜디오에서 serialVersionUID를 만듭니다.

관련 문제