본문 바로가기
Jave & Kotlin

Java - 간단한 게시판 구현을 통한 직렬화(Serialization) 이해하기(1) - 클래스 생성과 serialVersionUID 개념 및 설정방법

by devLog by Ronnie's 2021. 12. 23.

들어가며


직렬화에 대한 개념을 정리해보았으니 이번에는 코드 구현을 통해 직렬화에 대해서 좀 더 이해력을 높이고자 한다. 간단한 게시판을 구현해본다. 더불어 개념 설명시 빠져있던 serialVersionUID에 대해서도 같이 정리한다.

 

기본 개념 링크

https://sjparkk-dev1og.tistory.com/123

 

Java - 직렬화(Serialization)란? (implement serializable)

들어가며 보통 도메인 객체에 Serializable 인터페이스를 구현한 것을 볼 수 있다. 직렬화라는 것이 자바 시스템 내부에서 사용되는 객체나 데이터들을 외부의 자바 시스템에서도 사용하기 위해 바

sjparkk-dev1og.tistory.com

 

 

클래스 생성


먼저 직렬화 시킬 객체의 클래스를 작성한다. 이때 Serializable을 implements하는 것을 잊지 말자.

package com.company;

import java.io.Serializable;

// 직렬화하려는 클래스는 반드시 Serializable을 implements
public class Article implements Serializable {

    public int seq;
    public String writer, message;

    public Article(int seq, String writer, String message) {
        this.seq = seq;
        this.writer = writer;
        this.message = message;
    }

    @Override
    public String toString() {
        return seq + "\t" + writer + "\t" + message;
    }
}

 

 

SerialVersionUID


직렬화와 역직렬화를 얘기할 때 빼놓을 수 없는 것이 SerialVersionUID이다. 이름에서도 알 수 있듯이 고유한 ID이다. 이 ID값은 직렬화와 역직렬화 과정에서 값이 서로 맞는지 확인한 후에 처리를 하기 때문에 값이 맞지 않다면 InvalidClassException 예외가 발생하게 된다.(직렬화할 때 사용한 serialVersionUID의 값과 역직렬화 하기 위해 사용했던 serialVersionUID값이 다르다면 InvalidClassException이 발생) 하지만 자바에서는 SUID 값은 필수가 아니며 선언되어 있지 않으면 클래스의 기본 해시값을 사용하여 자동으로 값이 추가된다. (아래 자바 직렬화 스펙 내용과 링크를 첨부)

https://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

 

Java Object Serialization Specification: 4 - Class Descriptors

The serialized form of an ObjectStreamClass instance depends on whether or not the Class object it represents is serializable, externalizable, or a dynamic proxy class. When an ObjectStreamClass instance that does not represent a dynamic proxy class is wri

docs.oracle.com

 

SerialVersionUID 선언?


이제 직렬화와 역직렬화를 할때 SerialVersionUID가 사용되는 것도 알겠고 자동으로 생성해주는 것도 알겠으니 선언하지 않고 그냥 사용해도 되겠네라고 충분히 생각할 수 있지만 serialVersionUID는 선언해서 사용하는 것을 권장한다.

이유는 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에 컴파일러 구현체에 따라서 달라질 수 있어 역직렬화 과정에서 예상하지 못한 InvalidClassException을 유발할 수 있기 때문이다. 그러므로 서로 다른 자바 컴파일러 구현체 사이에서도 동일한 serialVersionUID을 얻기 위해서는 명시적으로 serialVersionUID 값을 선언해야한다. serialVersionUID을 선언할때는 static final이어야 하며 타입은 long타입이다. 그리고 가능한 serialVersionUID을 private로 선언하는 것을 권장한다. 상속되어 쓰여지는 것은 유용하지 않고 해당 클래스에서만 쓰일 것이기 때문.

  예) private(추천) static final long serialVersionUID = 42L;

 

SerialVersionUID 자동 생성하기


인텔리제이에서 SerialVersionUID을 자동 생성해주는 기능이 있어서 소개한다.

자동 생성 기능을 켜주면 되는데 먼저 기능을 켜기 전 모습을 확인해보자.

이제 기능을 켜보자. Settings or Preference에 들어가서 Serialization을 검색해주면 Inspections -> Serialization issues -> Serializable class without 'serialVersionUID' 옵션을 체크해준다.

기능을 키고 클래스에 마우스를 갖다 대보면 serialVersionUID을 추가할 수 있는 옵션이 생긴다.

 

마치며


생각보다 글이 길어져서 1, 2로 나눠서 정리한다. 다음 시간에는 게시판을 구현해보고 직렬화, 역직렬화를 코드를 통해 알아본다.

댓글