ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | Serialization 직렬화
    JAVA/JAVA 2020. 2. 7. 18:44

    Serialization 직렬화

    인스턴스의 어느 순간 상태를 그대로 저장하거나 네트워크를 통해 전송하는 것

    • 클래스의 인스턴스가 생성되면 인스턴스의 상태, 즉 인스턴스 변수 값은 계속 변화함
    • 직렬화로 인스턴스 내용을 연속 스트림으로 만듬
    • 스트림으로 만들어야 파일에 쓰거나 네트워크로 전송 가능
    • 직렬화 하고자 하는 클래스에서 반드시 Serializable 인터페이스를 구현해야 함
    • 직렬화시 모든 유형의 객체를 저장해야 하기 때문에 Object 클래스형으로 저장됨

    Deserialization 역직렬화

    저장된 내용이나 전송받은 내용을 다시 복원하는 것

    • 역직렬화를 할 때 클래스 정보가 존재하지 않을 수도 있으므로
      ClassNotFoundException 예외도 처리해야함
    • Object 클래스형으로 읽어 들인 객체를
      저장할 클래스 자료형에 맞게 형 변환(Downcasting) 해야 함

    ObjectInput / OutputStream

    직렬화를 도와주는 자바의 보조 스트림


    생성자

    생성자 설명
    ObjectInputStream(InputStream in) InputStream을 매개변수로 받아 ObjectInputStream 생성
    ObjectOutputStream(OutputStream out) OutputStream을 매개변수로 받아 ObjectOutputStream 생성

    메소드

    메소드 설명
    Object readObject() ObjectInputStream 클래스 일반 메소드
    객체 데이터를 스트림으로 불러올 때 사용
    void writeObject(Object obj) ObjectOutputStream 클래스 일반 메소드
    객체 데이터를 외부로 전송할 때 사용

    Serializable 인터페이스

    직렬화는 인스턴스 내용이 외부로 유출되는 것이므로 프로그래머가
    직렬화를 하겠다는 의도를 표시해야 하는데, 이 때 구현해야 하는 인터페이스

    • Marker Interface (마커 인터페이스)
      다른 기능은 없고 해당 클래스를 직렬화하겠다는 의사만 명시하는 인터페이스
    • 추상 메소드가 없는 인터페이스
      오버라이딩을 하지 않아도 됨(할 수 없음)

    형식

    class Person implements Serializable {
        // Java Code
    }

    transient 예약어

    직렬화 / 역직렬화 과정에서 제외하고자 하는 변수 앞에 작성하는 예약어

    사전적 의미: '일시적인, 일시적으로 머무르는'

    • 직렬화 될 수 없는 클래스(ex. Socket)가 인스턴스 변수로 있는 경우에 사용
    • 직렬화를 원치 않는 변수에 사용
    • transient 예약어를 사용한 변수에는 그 자료형의 기본 값이 저장됨
      ex) 객체 자료형의 경우 null 값이 저장됨

    형식

    transient 자료형 변수명;
    // transient String name;

    ※ name 변수에 null 값이 저장됨


    예제_직렬화

    Person 클래스 객체를 파일로 저장했다가 다시 불러옴

    package j200207;
    
    import java.io.*;
    
    // 직렬화 객체의 클래스는 반드시 Serializable 인터페이스를 구현해야 함
    class Person implements Serializable {
        String name;
        int age;
        String addr;
        // gender 변수는 직렬화 과정에서 제외함
        transient String gender;
    }
    
    public class ObjectTest {
    
        // Exception 하나로도 처리 가능
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    
            // Person 객체 생성
            Person p = new Person();
    
            // p 객체 변수 초기화
            p.name = "홍길동";
            p.age = 34;
            p.addr = "경기도 광명시";
            p.gender = "남자";
    
            // 객체 주소 출력
            System.out.println(p);    // j200207.Person@15db9742
    
            // p 객체 name, gender 변수 값 출력
            System.out.println(p.name);      // 홍길동
            System.out.println(p.gender);    // 남자
    
            // 한글이 있지만 객체를 저장하기 때문에 FileOutputStream 사용
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
    
            // p 객체를 파일에 작성
            oos.writeObject(p);
    
            // 스트림 사용 후 메모리 해제
            oos.close();
    
            // 파일을 불러오는데 객체 자료형에 맞게 불러오도록 하는 스트림 객체 생성
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
    
            // 모든 유형의 객체를 저장해야 하기 때문에 Object 클래스형으로 저장됨
            Object pr = ois.readObject();
    
            // pr 객체가 Person 클래스의 인스턴스인지 확인
            System.out.println(pr instanceof Person);    // true
            System.out.println(pr);        // j200207.Person@3b07d329
    
            // pr 객체를 Person 자료형의 pp 객체로 형 변환(Downcasting)
            Person pp = (Person) pr;
    
            // pp 객체 주소 출력
            System.out.println(pp);         // j200207.Person@3b07d329
    
            // pp 객체 name 변수 값 출력
            System.out.println(pp.name);    // 홍길동
    
            // pp 객체 gender 변수 값 출력
            System.out.println(pp.gender);  // null
    
            // 스트림 사용 후 메모리 해제
            ois.close();
    
        }
    
    }

    객체의 형태를 유지하면서 외부로 전송하거나 내부로 불러 들이는 직렬화에 대해 알아보았습니다.

    직렬화를 사용하는 경우 데이터가 유출되는 것이기 때문에

    이에 대해 Serializable 인터페이스를 구현함으로써 명시해야 합니다.

    또한 transient 예약어를 사용하면 외부로의 유출을 원하지 않는 변수에 기본 값을 저장함으로써

    데이터의 정보를 안전하게 보호할 수 있겠습니다.

    'JAVA > JAVA' 카테고리의 다른 글

    Java | Wrapper Class  (0) 2020.02.07
    Java | I/O File Class  (0) 2020.02.07
    Java | I/O 보조 스트림  (0) 2020.02.06
    Java | I/O 문자 단위 스트림  (0) 2020.02.06
    Java | I/O 바이트 단위 스트림  (0) 2020.02.06

    댓글

Designed by Tistory.