코딩마을방범대
직렬화(Serialization) 란? 본문
코드 분석을 하다보면 Serializable라는 인터페이스를 마주칠 수 있다.
직렬화라는 것은 많이 들어봤지만 정확한 개념을 모르고 있었는데 이 참에 포스팅을 해볼 것이다!
직렬화(Serialization) 란?
- 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술
*역직렬화(Deserialization): 바이트로 변환된 데이터를 다시 객체로 변환하는 기술 - JVM(Java Virtual Machine)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술
객체 저장은 ObjectOutputStream 클래스를 사용
객체 읽기는 ObjectInputStream 클래스를 사용
Serializable 인터페이스 구현
1. serialVersionUID 변수 설정
serialVersionUID는 클래스의 버전을 나타내는 고유 식별자로, 직렬화된 데이터와 클래스 정의 간의 호환성을 유지하는 데 사용된다.
(만약 별도로 지정하지 않으면, 자바 소스가 컴파일될 때 자동으로 생긴다.)
반드시 static final long으로 선언해야 하며, 변수명도 serialVersionUID로 선언해 주어야 자바에서 인식 할 수 있다.
예시: A서버의 SerialDTO 객체를 B서버로 전송하는 상황
전송하는 A 서버와 전송받는 B 서버에는 SerialDTO라는 클래스가 있어야 한다.
만약 A 서버가 갖고 있는 SerialDTO에는 변수가 3개 있고, B 서버의 SerialDTO에는 변수가 4개 있는 상황이라면 자바에서는 제대로 처리할 수가 없다.
각 서버가 객체가 동일한지 확인할 수 있도록 하기 위해서는 serialVersionUID로 관리를 해주어야 한다.
클래스 이름이 같고 UID가 다르거나, UID가 같고 변수의 개수나 타입 등이 다르면 다른 클래스로 인식 한다.
2. 직렬화에 필요없는 변수는 transient 예약어를 추가
보안상 중요한 변수(패스워드 등)나 저장할 필요가 없는 변수는 transient를 통해 직렬화 대상에서 제외 시킬 수 있다.
아래와 같이 기존 변수 선언 앞에 transient를 추가해주면 된다.
transient private int bookSeq;
💡 TIPS!
1. 상속 관계의 직렬화
public class SuperUserInfo implements Serializable {
String name;
String password;
}
public class UserInfo extends SuperUserInfo {
int age;
}
위와 같이 직렬화를 구현한 클래스를 상속받은 경우 자식 클래스인 UserInfo를 직렬화하면 부모 클래스의 name, password도 같이 직렬화가 된다.
하지만 부모 클래스가 직렬화를 구현하지 않고 자식 클래스에서 직렬화를 구현했을 경우 name, password는 직렬화 대상에서 제외된다.
public class SuperUserInfo {
String name;
String password;
}
public class UserInfo extends SuperUserInfo implements Serializable {
int age;
}
2. Object 클래스는 직렬화가 불가하다
public class UserInfo implements Serializable {
int age;
Object object = new Object();
}
위 클래스를 직렬화 시도하면 java.io.NotSerializableException 이 발생한다.
1번에서 보았다시피 부모 클래스에서 직렬화를 구현하면 자식 클래스에서도 직렬화가 가능했다.
Object는 모든 클래스의 최고 조상이기 때문에 직렬화를 구현했다면 모든 클래스에서 직렬화가 가능했을 것이다.
하지만 Object 클래스를 들어가보면 직렬화 구현이 되어 있지 않은 것을 알 수 있다.
이 때문에 Object 자체를 변수로 가질 경우 직렬화 구현이 불가능해 오류가 발생하는 것이다.
아래와 같이 Object 타입을 가지고 있지만 실제 초기화된 객체가 직렬화를 구현한 클래스라면 오류가 발생하지 않는다.
(아래 사진을 보면 String은 직렬화를 구현하고 있음을 알 수 있다.)
public class UserInfo implements Serializable {
int age;
Object object = new String("abc");
}
3. Serializable 인터페이스에는 왜 아무것도 구상되어있지 않을까?
Serializable 인터페이스에 들어가보면 아무것도 구상되어있지 않은 상태임을 알 수 있다.
Serializable 인터페이스는 마커(marker) 인터페이스이며,
단순히 클래스가 직렬화 가능함을 표시하는 역할을 하기 때문이다.
마커(maker) 인터페이스란?
아무런 메서드도 정의하지 않는 인터페이스
해당 인터페이스를 구현한 클래스에 대한 정보를 JVM에게 제공하는 역할을 한다.
참고사이트
[Java] 직렬화(Serialization)란 무엇일까?
'💡 백엔드 > Java' 카테고리의 다른 글
소나큐브 7.2.1 버전에서 새로운 프로젝트 등록하기 (1) | 2024.06.28 |
---|---|
소나큐브 코드스멜 테스트 결과 메시지 분석 (0) | 2024.06.27 |
JAVA의 try-with-resources (0) | 2024.06.25 |
SonarQube 에 GitLab&Local 연결해서 사용하기 (0) | 2024.06.17 |
WAR 파일을 이용해 Intellij 디버깅 모드로 실행시키기 (0) | 2024.05.08 |