자바 직렬화 Serializable, Externalizable 예제로 이해하기

반응형
728x90
반응형

Serializable

interface Serializable.java
public interface Serializable {
}

 

Person.java
class Person implements Serializable {
    String name;
    String job;
    // transient String job; // transient : 이 멤버는 직렬화 대상에서 제외한다. (default 값 null 로 출력될거임)

    public Person() {

    }

    public Person(String name, String job) {
        this.name = name;
        this.job = job;
    }

    public String toString() {
        return name + "," + job;
    }
}

 

SerializationTest.java
public class SerializationTest {
    public static void main(String[] args) {
        Person personLee = new Person("테스트", "개발자");
        Person personKim = new Person("테스투", "기획자");

        try (FileOutputStream fos = new FileOutputStream("serial.txt")) {
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            /**
             * NotSerializableException 에러 발생 : 클래스에 implements Serializable
             */
            oos.writeObject(personLee);
            oos.writeObject(personKim);

        } catch (IOException e) {
            System.out.println(e);
        }

        try (FileInputStream fis = new FileInputStream("serial.txt")) {
            ObjectInputStream ois = new ObjectInputStream(fis);

            // readObject 할때 클래스의 정보가 없으면 에러 발생 */
            Person pLee = (Person) ois.readObject();
            Person pKim = (Person) ois.readObject();

            System.out.println(pLee);
            System.out.println(pKim);
        } catch (IOException | ClassNotFoundException e) {
            System.out.println(e);
        }
    }
}

 

 

  • 1) implements Serializable 을 추가하자.
class Person implements Serializable

 

Serializable 인터페이스를 구현하지 않으면, NotSerializableException 에러가 발생한다.

 

 

  • 2) 클래스의 정보와 일치하는지 확인하자.
 Person pKim = (Person) ois.readObject();

 

readObject() 의 결과에 해당 클래스의 정보가 없으면 ClassNotFoundException 에러가 발생한다.

 

 

Externalizable

interface Externalizable.java
public interface Externalizable extends java.io.Serializable {
    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

 

Member.java
class Member implements Externalizable {
    String name;
    String job;
    // transient String job; // transient : 이 멤버는 직렬화 대상에서 제외한다. (default 값 null 로 출력될거임)

    public Member() {

    }

    public Member(String name, String job) {
        this.name = name;
        this.job = job;
    }

    public String toString() {
        return name + "," + job;
    }

    /**
     * 직접 구현
     * @param out
     * @throws IOException
     */
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(this.name);
        out.writeUTF(this.job);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.name = in.readUTF();
        this.job = in.readUTF();
    }
}

 

ExternalizableTest.java
public class ExternalizableTest {
    public static void main(String[] args) {
        Member memberLee = new Member("테스트", "개발자");
        Member memberKim = new Member("테스투", "기획자");

        try (FileOutputStream fos = new FileOutputStream("serial.txt")) {
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(memberLee);
            oos.writeObject(memberKim);

        } catch (IOException e) {

            System.out.println(e);
        }

        try (FileInputStream fis = new FileInputStream("serial.txt")) {
            ObjectInputStream ois = new ObjectInputStream(fis);

            // readObject 할때 클래스의 정보가 없으면 에러 발생 */
            Member pLee = (Member) ois.readObject();
            Member pKim = (Member) ois.readObject();

            System.out.println(pLee);
            System.out.println(pKim);
        } catch (IOException | ClassNotFoundException e) {
            System.out.println(e);
        }
    }
}

 

  • 1) implements Externalizable 을 함으로써 메서드 재정의 필요
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        ...
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        ...
    }

 

 

transient 필드

transient 가 선언된 필드는 직렬화 대상에서 제외한다. 제외할 경우 해당 타입의 default 값으로 출력된다.

transient String job;

 

String 타입의 변수이므로 null 이 출력된다.

 

 

 

반응형

Designed by JB FACTORY