[JAVA] 직렬화

ho's·2022년 5월 19일
0

ObjectInputStream, ObjectOutputStream

  • 직렬화 가능한 대상을 읽고 쓸 수 있다.
  • 직렬화 가능한 대상은 기본형 타입 or java.io.Serializable 인터페이스를 구현하고 있는 객체이다.

객체를 옮길 수 있는 기술을 직렬화 라고 한다.

객체직렬화 예제

Step1)

  1. User Class 생성하고, Serializable을 상속받는다.

  1. private한 field 이므로, 외부에서 접근 가능하게 하기 위해 생성자를 만들고, getter, toString()을 이용해 코드를 작성한다.
package totojava.io;

import java.io.Serializable;

public class User implements Serializable {
    private String email;
    private String name;
    private int birthYear;

    public User(String email, String name, int birthYear) {
        this.email = email;
        this.name = name;
        this.birthYear = birthYear;
    }

    @Override
    public String toString() {
        return "User{" +
                "email='" + email + '\'' +
                ", name='" + name + '\'' +
                ", birthYear=" + birthYear +
                '}';
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    public int getBirthYear() {
        return birthYear;
    }
}

Serializable을 직렬화 하기 위해서는 field도 직렬화 가능해야 한다.

int는 기본형 TYPE이기 때문에 직렬화 가능하다.
만약 A타입의 변수 a가 Serializable을 구현하고 있지 않다면 직렬화 하지 않는다.

위의 내용을 파일에 저장해 보자!

User 객체를 생성하자

User user = new User("hong@example.com", "홍길동", 1992);

저장할 위치를 정해서 저장하는 코 ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\Users\handa\Desktop\file\info.txt"));

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/tmp/user.dat"));

객체를 파일에 저장하는 코드

out.writeObject(user);

파일 읽어들이기

ObjectInputStream으로 읽어들이는 코드

ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\Users\\handa\\Desktop\\file\\info.txt"));

  • FileInputStream을 통해서 ObjectInputStream을 읽어들인다.

readObject(); 는 Object타입을 읽어들인다. 따라서 원래 형태인 User로 형변환을 해줘야 한다.

User user = (User) in.readObject();

읽어 들인 후, 반드시 close()를 해준다
in.close();

직렬화를 이용하면 파일을 통해 복사하는 것과 같은 효과를 가진다!

원래 인스턴스를 new 연산자로 생성하지만, 위의 코드는 readObject()가 file로부터 인스턴스 정보를 입력받아, 인스턴스를 만들어 내고 그것을 user에 담았다.
즉 파일에 있는 데이터를 읽어들인 것이다.

예제2

유저 정보가 많을땐 어떻게 해야할까

user가 3명이 있다고 하고, 3명의 객체를 만들자.

ArrayList의 클래스를 들어가서 자세히 들여다 보자.

java.io.Serializable을 구현하고 있는 것을 볼 수 있다.

즉, ArrayList, user 모두 직렬화 가능하다.

파일 읽어들이기

예제1 에서 했던 방법이랑 비슷하다.

ArrayList<User> list = (ArrayList)in.readObject();

ArrayList로 저장했으니, ArrayList로 형변환을 해서 받아 들여야 한다.

for(int i=0;i<list.size();i++){
	System.out.println(list.get(i));
}

list의 size만큼 반복해서 출력한다.

얕은 복사

User의 정보를 변경하게 되면 list1, list2의 User의 정보 또한 같이 변하게 된다.

예제3 객체 직렬화를 통해 깊은 복사하는 방법

메소드를 따로 빼어내서 만든 코드

이렇게 작성을 하면 진짜 인스턴스가 2개가 생성이 된다.

자바에서는 깊은 복사를 통해 다양한 일을한다.

  • 어떤 객체를 임시적으로 디스크로 저장했다가 읽어들인다.
  • 어떤 객체들을 메모리상에 복제를 한다.
  • 라이브러리, 프레임워크 사용시 직렬화 가능이라는 말은 Serializable 인터페이스를 구현하고 있거나, 기본형타입을 사용하고 있으면 직렬화 가능하다.

정리

ObjectInputStream, ObjectOutputStream

  • 직렬화 가능한 대상을 읽고 쓸 수 있다.
  • 직렬화 가능한 대상은 기본형 타입 or java.io.Serializable 인터페이스를 구현하고 있는 객체이다.
profile
그래야만 한다

0개의 댓글