본문 바로가기

Language & Framework/Java

자바 예외 (2) java.io.InvalidClassException: InputAndOutput.Child; no valid constructor

java.io.InvalidClassException: InputAndOutput.Child; no valid constructor
	at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:169)
	at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:885)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2187)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1669)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:503)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:461)

 

- InvalidClassException의 원인

(1) 클래스의 Serial 버전이 다른 경우

(2) 알 수 없는 데이터 타입을 포함한 경우

(3) 기본 생성자가 없는 경우

 

- no valid constructor ?

유효한 생성자가 없다. 어떤 의미일까?

 

 

 

나는 Child 클래스를 직렬화한 뒤 역직렬화하는 과정에서 해당 예외와 맞닥뜨리게 되었다.

객체의 deserialization(역직렬화) 과정에서 non-seralizable(직렬화를 구현하지 않은)한 부모로부터 상속 구조를 따라 내려오게 된다.

문제는 직렬화시 부모의 인스턴스 변수는 직렬화되지 않았기 때문에 역직렬화할 스트림이 존재하지 않는다. 따라서 기본값을 불러오게 되는데 이 때 불러올 vaild constructor, 즉 유효한 생성자가 없다는 뜻이다.

 

 

 

해결책 1. 기본 생성자 만들기

위와 같이 기본 생성자를 만들어주면 정상적으로 실행되는 것을 확인할 수 있다.

 

 

 

해결책 2. writeObject, readObject 메서드 구현으로 상속받은 인스턴스 변수값을 직접 직렬화처리하기.

1번 방법으로는 예외 자체는 처리할 수 있지만 기본 생성자에서 정의한 값 밖에 쓸 수 없다는 문제가 존재한다.

이렇게 writeObject와 readObject 메서드를 구현해주면 직렬화 및 역직렬화 시 자동으로 적용된다.