본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Serialization 을 사용할 때 다음의 예외를 고려하자.

by 돼지왕 왕돼지 2015. 12. 17.
반응형

 [android] Serialization 을 사용할 때 다음의 예외를 고려하자.


Android, ClassNotFoundException, Compiler, deserialize, invalidclassexception, IOException, lookup, ObjectInputStream, ObjectOutputStream, ObjectStreamClass, package, readClassDescriptor, SecurityException, Serialization, serialVersionUID, [android] Serialization 을 사용할 때 다음의 예외를 고려하자., 고려, 매치, 명시, 변경, 예외, 위험, 컴파일러, 환경


serialVersionUID 를 명시적으로 주자.


serialVersionUID 를 명시적으로 주지 않으면, compiler 가 계산한 값을 부여한다.
환경이 변하지 않으면 좋겠지만, compiler 가 계산한 값은 상황에 따라 값이 달라질 수 있다.
serialVersionUID 가 매치하지 않는 경우에 deserialize 하려고 시도하면 InvalidClassException 이 발생한다.

잠재적 위험을 피하기 위해 serialVersionUID 를 명시적으로 주는 것이 좋다.

만~약 이전 버전에 이미 compiler 가 자동으로 할당한 serialVersionUID 값을 사용하게 되었다면,
그 값을 찾아 명시적으로 설정해주어야 하위 호환성을 확보 할 수 있다.



Serializable 을 상속하는 Class 의 package 를 변경할 떄는 ObjectInputStream 을 상속해 사용하자.


package 가 변경된 경우 ClassNotFoundException 이 발생한다.
따라서 Serializable 을 상속하는 Class 의 package 를 변경할 때는
아래와 같이 ObjectOutputStream 을 상속하여 deserialize 해줘야 한다.


public class MyInputStream extends ObjectInputStream {
    public Map<String, Class> classNameMap = initClassNameMap();

    private static Map<String, Class> initClassNameMapping() {
        Map<String, Class> map = new HashMap<String, Class>();
        map.put("com.test.oldpackage", com.test.newpackge.Test.class);
        return Collections.unmodifiableMap(map);
    }

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

    protected MyInputStream() throws IOException, SecurityException {
        super();
    }

    @Override
    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
        ObjectStreamClass desc = super.readClassDescriptor();
        if (classNameMapping != null && classNameMapping.containsKey(desc.getName())) {
            return ObjectStreamClass.lookup(classNameMapping.get(desc.getName()));
        }
        return desc;
    }
}






반응형

댓글