자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술
각자 PC의 OS마다 서로 다른 가상 메모리 주소 공간을 가지기 때문에 Reference Type의 데이터들은 인스턴스를 전달할 수 없다.
이 문제를 해결하기 위해서는 주소값이 아닌 Byte형태로 직렬화된 객체 데이터를 전달해야한다.
직렬화 된 데이터들은 모두 Primitive Type이 되고, 이는 파일 저장이나 네트워크 전송 시 파싱이 가능한 유의미한 데이터가 된다.
따라서, 전송 및 저장이 가능한 형태로 만들어주는 것이 직렬화(Serialization) 이다.
조건
자바에서는 간단히 java.io.Serializable
인터페이스 구현으로 직렬화 / 역직렬화가 가능하다.
- 직렬화 대상: Serializable 인터페이스를 상속받은 객체 or Primitive Type의 데이터
직렬화 구현
Serializable 인터페이스를 구현하면 SUID를 선언해야한다.
serialVersionUID는 Default 값으로 클래스의 기본 해쉬값을 가지고 있는데, 직렬화 된 데이터를 다른 클래스가 전달받아 역직렬화를 하게 되면 java.io.InvalidClassException
이 발생할 수 있다.
위 Exception이 발생하는 이유는 직렬화 하는 시스템과 역직렬화하는 시스템이 다른 경우에 발생하는데, 각 시스템에서 사용하고 있는 모델의 버젼 차이가 발생했을 경우에 생기는 문제이다.
ex) Class의 속성이 추가되어 멤버변수가 더 많을 때
이렇게 모델의 버전 간 호환성을 유지하기 위해서는 SUID를 정의해야 한다.
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private String userId;
private String userName;
}
public static void main(String[] args){
User user = new User("id","name");
byte[] serializedUser;
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()){
try(ObjectOutputStream oos = new ObjectOutputStream(baos)){
oos.writeObject(user);
serializedUser = baos.toByteArray();
}
}
}
위와 같이 ObjectOutputStream
클래스를 이용해 직렬화를 진행하면 byte로 변환된 값을 얻을 수 있다.
역 직렬화 구현
public static void main(String[] args){
byte[] serializedUser;
try(ByteArrayInputStream bais = new ByteArrayInputStream(serializedUser)){
try(ObjectInputStream ois = new ObjectInputStream(bais)){
Object objectUser = ois.readObject();
User user = (User) objectUSer;
}
}
}
ObjectInputStream
클래스로 byte값을 다시 객체로 만들 수 있게 된다.
직렬화 데이터는 타입, 클래스 메타정보를 포함하므로 사이즈가 크다.
트래픽에 따라 비용 증가 문제가 발생할 수 있기 때문에
표 형태의 다량의 데이터 -> CSV
구조적인 데이터 -> XML, JSON
위와 같은 포맷으로 직렬화 하는 것이 좋다.
JSON 포맷으로 직렬화를 하기 위해서는 Jackson이나 Gson라이브러리를 사용하면 된다.
'Study > JAVA' 카테고리의 다른 글
[JAVA] Wrapper Class (0) | 2022.01.05 |
---|---|
[JAVA] Call by Value & Call by Reference (2) | 2021.12.31 |