자바 - Serializable

well-life-gm·2021년 11월 5일
0

자바

목록 보기
1/1

자바에서 인스턴스화 된 객체를 디스크에 영속적으로 저장하거나, 네트워크를 통해 다른 서버로 보내기 위해서 직렬화라는 것을 사용한다.
다음과 같은 Plant Class가 있고, 이를 저장하려고 한다.

package com.example.SavePlant;

public class Plant {
    String name;
    transient Integer year;	// 직렬화시 제외하고 싶은 데이터
    String type;

    public Plant(String name, Integer year, String type) {
        this.name = name;
        this.year = year;
        this.type = type;
    }
    
    @Override
    public String toString() {
        return "[name : " + this.name + "] [year: " + this.year + "] [type : " + this.type + "]";
    }
    ... 다른 메서드는 생략
}

package com.example.SavePlant;

import com.example.SavePlant.Plant;

import java.io.*;
import java.util.ArrayList;

public class SavePlant {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		String fileName = "sj.ser";
        
        // 영속화를 위한 IO Stream 열기
		FileOutputStream fo = new FileOutputStream(fileName);
		BufferedOutputStream bo = new BufferedOutputStream(fo);
		ObjectOutputStream out = new ObjectOutputStream(bo);

		// 테스트 데이터들
		Plant firstPlant = new Plant("식물1", 1, "타입1");
		Plant secondPlant = new Plant("식물2", 2, "타입1");
		Plant thirdPlant = new Plant("식물3", 3, "타입1");

		ArrayList al = new ArrayList();
		al.add(firstPlant);
		al.add(secondPlant);
		al.add(thirdPlant);

		out.writeObject(al);

		out.close();
		bo.close();
		fo.close();

		// 역직렬화
		FileInputStream fi = new FileInputStream(fileName);
		BufferedInputStream bi = new BufferedInputStream(fi);
		ObjectInputStream in = new ObjectInputStream(bi);

		ArrayList<Plant> list = (ArrayList)in.readObject();
		Plant[] array = list.toArray(new Plant[list.size()]);
		for(Plant plant : array) 
			System.out.println(plant.toString());

		in.close();
		bi.close();
		fi.close();
	}
}

IO를 위한 스트림을 열었고, writeObject를 통해 올바르게 객체를 적었다고 생각하지만 위 코드는 아래와 같은 에러를 띄운다.
에러
위 에러 메시지의 코드를 타고 가다보면 에러를 발생시키는 아래 코드를 볼 수 있다.
즉, Stream을 하려는 객체가 Serializable 마커 인터페이스를 붙이고있지 않아서 발생한다는 것을 알 수 있다.
코드

에러를 해결하기 위해선 아래와 같이 Plant 클래스에 Serializable 마커 인터페이스를 붙여주면 된다.

package com.example.SavePlant;

import java.io.Serializable;

public class Plant implements Serializable {
    String name;
    transient Integer year;	// 직렬화시 제외
    String type;

    public Plant(String name, Integer year, String type) {
        this.name = name;
        this.year = year;
        this.type = type;
    }
    
    @Override
    public String toString() {
        return "[name : " + this.name + "] [year: " + this.year + "] [type : " + this.type + "]";
    }
}

Serializable을 붙이고 난 뒤에 실행하면 아래와 같이 정상적으로 실행된다.

결과

위와 같이 trasient를 붙인 멤버에 대해서는 직렬화를 하지 않아서, 역직렬화시 null로 출력이 되는 것을 알 수 있다.

profile
내가 보려고 만든 블로그

0개의 댓글

관련 채용 정보