위 페이지를 번역한 내용입니다.
java.io.InvalidClassException 은 Object Serialization 을 사용하다보면 흔히 접할 수 있는 오류이다. 이 오류는 3가지 주요 원인이 있는데, 이는 다음과 같다.
- 클래스의 Serial 버전이 다른 경우
- 알 수 없는 데이터 타입을 포함한 경우
- 기본 생성자가 없는 경우
여기서는 디폴트 생성자가 없는 경우를 살펴보도록 하자.
InvalidClassException 이란?
이름에서도 알 수 있듯이, Serialized 또는 Deserialized 된 객체가 위에서 언급한 3가지 이유 중 하나로 invalid 한 상태가 된다.
이로 인해 Serialized 또는 Deserialized 할 수 없다.
ObjectStreamException 을 상속하고 있는 Exception 이다.
InvalidClassException : no valid constructor 는 언제 발생하나?
InvalidClassException 은 프로그램 내에 상속이 있을 때 발생한다.
상속구조에서 Serialization 은 자식 클래스부터 Serializing 한 뒤 상위(부모) Object 로 이동해서 Serializing 하게되며, non-serializable 한 부모 클래스까지 수행된다.
객체가 Deserialized 될 때, non-serializable 한 부모 클래스부터 시작해서 상속구조를 따라 내려간다.
부모 클래스가 non-serializable 하기 때문에 부모 클래스들의 속성정보들을 기본 생성자를 통해서 가져올 수 있는데, 이를 Stream 으로부터 가져올 수 없기 때문에 발생한다.
이런 정보들은 기본 생성자로부터만 받아올 수 있는데, 기본 생성자가 없다면 객체가 invalid 한 상태가 된다.
예제) InvalidClassException
public class JavaIoInvalidClassException {
public static void main(String[] args) { Child1 c1 = new Child1("child1"); try { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("sample.dat")); out.writeObject(c1); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream("sample.dat")); Parent p = (Child1) in.readObject(); in.close(); } catch (Exception e) { e.printStackTrace(); } } } class Parent { String parameterName; public Parent() { } public Parent(String name) { this.parameterName = name; } } class Child1 extends Parent implements Serializable { public Child1(String name) { super(name); } }
|
java.io.InvalidClassException: com.tomining.java_tutorial.exception.Child1; no valid constructor
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:150) at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:768) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.tomining.java_tutorial.exception.JavaIoInvalidClassException.main(JavaIoInvalidClassException.java:25)
|
위 프로그램은 Child1 클래스가 Parent 클래스를 상속하고 있다. Child1 은 Serialzable 하다.
Deserialized 할 때, 부모 클래스의 기본생성자를 찾는데, 부모클래스에는 기본생성자가 존재하지 않기 때문에 Exception 이 발생하는 것이다.
해결책
부모클래스에 기본 생성자를 생성해 주면 된다.
class Parent {
String parameterName; public Parent() { } public Parent(String name) { this.parameterName = name; } }
|
'Programing > Java' 카테고리의 다른 글
PowerMockito 를 이용하여 private method Mock 처리하기 (0) | 2015.12.31 |
---|---|
javax.net.ssl.SSLProtocolException 해결책 (0) | 2015.12.31 |
Serializable 과 transient (0) | 2015.06.29 |
[자바8 람다의 힘] 3장 String, Comparator 그리고 filter (0) | 2015.04.01 |
Java의 System.out을 파일 출력으로 변경하는 방법 (0) | 2015.03.30 |