cleanUrl: /posts/java-what-is-serializable-and-deserializable
share: true

Effective java 에서 직렬화를 최대한 사용하지 말라는 내용이 있었으나 팀에선 Serializable 을 구현한 클래스를 매우 자주 보게 되었다. 가장 큰 이슈는 보안에 관련한 문제였고, 이것을 명확히 알고 사용한다면 상당히 유용하다고 하여 알아보도록 한다.

<aside> 💡 직렬화: 데이터를 Stream 으로 전송할 수 있는 상태로 만든다 (ex. 파일) 역직렬화: Stream 으로 전송 받은 데이터를 객체로 만든다

</aside>

직렬화의 전제 조건은 Serializable 을 구현하는 것이다.

public class Beverage implements Serializable {

}
public class Coffee extends Beverage {

}

IntelliJ 에서 serialVersionUID 생성하기

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ed1a8a00-4a5b-4e49-a209-7259bf128f79/Screen_Shot_2021-07-24_at_2.54.11_AM.png

serialVersionUID 를 편하게 만들고 싶다면 preference → inspection → Serializable class without 'serialVersionUID' 를 체크하고

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a6283e24-b901-438e-ae6d-df8b420ee50f/Screen_Shot_2021-07-24_at_2.55.30_AM.png

클래스 이름에 커서를 갖다 두면 이러한 메세지 창이 나오는데 Add 'serialVersionUID' field 를 클릭하면 된다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/16657b68-3d55-4ae0-9610-744447bd61e4/Screen_Shot_2021-07-24_at_2.56.04_AM.png

serialVersionUID 필드를 생성했다.

직렬화 대상에서 제외하기 (transient)

보안상의 이슈, 혹은 직렬화로 보여줄 필요가 없는 내부 정보를 숨길 때 사용한다.

HashMap 내부에 숨겨진 field 들

HashMap 내부에 숨겨진 field 들

실제로 HashMap 을 사용하면서 이 값들을 직접 제공하는 일은 없다. 모두 public API 로 제공하거나 내부적으로 error 을 확인하여 fail fast 용도로 사용한다.

다른 객체를 member 로 갖고 있다면

public class Beverage implements Serializable {

    private static final long serialVersionUID = -2869694270928466514L;

    private transient String partnerName;
    private LocalDateTime orderAt;

    private BeverageName name;
    private BeverageSize size;

}