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 메서드를 구현해주면 직렬화 및 역직렬화 시 자동으로 적용된다.
'Language & Framework > Java' 카테고리의 다른 글
대혼돈의 질서 파괴범 Reflection API에 대해 알아보자 (Java) (2) | 2022.09.11 |
---|---|
Interface와 Abstract의 차이는 무엇인가? - - 22/08/07 내용 추가 (0) | 2022.07.13 |
자바 예외 (1) java.io.NotSerializableException (0) | 2022.06.21 |
자바 ArrayList와 LinkedList는 무엇인가? 성능 비교 (+ Vector..?) (0) | 2022.06.12 |
자바 Wrapper 클래스의 기본 활용 (0) | 2022.06.09 |