SerialVersionUID는 무엇이고 이를 선언해야 하는 이유가 무엇일까요?

2023. 9. 22. 16:18·Computer Science/Java
728x90
서론

안녕하세요. is낫널입니다.

나중에 이름을 바꾸게 될 수도 있지만 지금은 마음 가는 대로 짓게 된 이름인데 제 가치관을 표현해 줄 이름으로 

생각해 내서 바꿔보려구요. 그게 이 블로그를 들어오는 사람들에게 제 이미지가 됐으면 좋겠네요! 

오늘은 날이 되게 따뜻합니다. 이런 날도 이제 얼마 남지 않았어요. 곧 겨울이 올 것 같습니다. 

12월이 되기 전에 취직을 해서 삿포로 가고 싶네요.

아 좀 주저리주저리 하는 타입이라, 의식의 흐름대로 말이 나오는 것 같습니다 ㅋㅋㅋ 

이제 시작할게요. 

 

SerialVersionUID를 선언해야 하는 이유

먼저 이 글을 들어온 이유로 이게 가장 궁금한 부분일 거 같습니다. 

그래서 두괄식으로 결론부터 딱 내놓자면

직렬화 할 때와 역직렬화할 때 SerialVersionUID 라는 클래스의 버전이 일치해야 하기 때문입니다. 

 

자세히 설명하자면, SerialVersionUID 라는 클래스의 버전은 객체가 직렬화될 때

클래스에 정의된 멤버변수의 정보를 이용해서 자동으로 생성되어 직렬화 내용에 포함됩니다. 

그리고 역직렬화 할 때 클래스의 버전을 비교함으로써, 직렬화할 때의 클래스 버전과 일치하는지 확인할 수 있는 것입니다. 

 

SerialVersionUID 의 값이 달라지는 이유

그렇다면, 왜 SerialVersionUID의 값이 달라지는 일이 발생하게 되는 걸까요? 

보통 SerialVersionUID의 값이 자동으로 생성되는 데 있어, 역직렬화할 때 클래스의 버전이 갑자기 달라지는 경우가 크게 없지만 
직렬화했던 클래스의 내용이 변경되었을 경우 새로운 SerialVersionUID 를 자동 생성하기 때문에 기존 역직렬화가 구성된 클래스에서 

클래스 버전이 일치하지 않다는 에러문구가 뜨게 됩니다. 

 

이유는 SerialVersionUID 의 값을 생성해 내는 계산은 클래스의 세부사항에 매우 민감하게 반응하기 때문에

컴파일러 구현체에 따라서 달라질 수 있어서 역직렬화 과정에서 예상하지 못한 InvalidClassException 에러를 유발할 수 있습니다.

이것은 클래스의 이름이 똑같다고 하더라도 클래스 버전이 달라지는 경우가 발생합니다. 

 

하지만 만약 여기서, static 변수나 transient 키워드가 붙은 인스턴스변수는 직렬화에 영향을 끼치지 않기 때문에

클래스의 버전을 다르게 인식하도록 할 필요가 없습니다. 

static 에 대해서는 보통 아실 테지만, transient 키워드는 직렬화 대상을 제외시키도록 하는 제어자입니다. 

이 키워드가 어떨 때 쓰이는지는 밑에서 조금 더 자세히 설명하도록 하겠습니다. 

 

 

SerialVersionUID 를 수동으로 설정하는 방법

자동으로 생성되는 경우가 아닌, 직접 사용자가 수동으로 설정하는 방법은 어떻게 해야 하는지 간단하게 설명해 보겠습니다.
SerialVersionUID 의 값은 정수값이면 어떠한 값으로도 지정할 수 있지만, 서로 다른 클래스 간에 같은 값을 갖지 않도록

serialver.exe 를 사용해서 생성된 값을 사용하는 것이 보통이라고 합니다.

그래서 serialver.exe 뒤에 SerialVersionUID 를 얻고자 하는 클래스 이름만 적어주면

클래스의 SerialVersionUID 를 얻어낼 수 있게 됩니다. 

그러나, 이클립스 3.3 이후부터는 serialver.exe 로 생성되는 값을 자동으로 생성해 주는 방식이 생겼는데

사진으로 설명드리겠습니다. 

 

먼저 직렬화가 구현되어있는 클래스에서 노란색 경고표시가 뜨고 있는 것을 확인할 수 있습니다.

이때 빨간색이 아닌 노란색인 이유는 SerialVersionUID의 값이 자동으로 생성되기는 하나, 수동으로 선언하는 것을 권장하기 때문에 

이클립스 쪽에서는 노란색으로 경고표시를 띄우는 것입니다. 

그러면 저 노란색 밑줄이 그어진 Person 위에 마우스를 올리면 SerialVersionUID 값을 생성할 수 있는데

default 는 기본값이므로 1L 를 생성해 주기 때문에, 그 아래의 generated SerialVersionUID 값을 눌러줘야 합니다

출처 : 스크린샷도 아니고, 제가 직접 찍은 사진인데 그러게요 .. 왜 스크린샷이 안될까요 하하

 

누르게 되면 이와 같이 SerialVersionUID 값이 생성되는 것을 확인할 수 있습니다. 

출처 : 마우스 올리면 뜨는 부분만 스크린샷을 못해서 이렇게 그냥 스크린샷 찍는건 가능하더라구요. 어쨌든 출처는 접니다!

 

transient 란?

아까 설명드리기로 한 transient 제어자에 대해서 짚고 넘어가보겠습니다. 

간단하게 위에서도 언급했었지만, 제어자 transient 를 인스턴스 변수 앞에 붙이게 되면, 직렬화 대상에서 제외할 수 있게 됩니다. 

 

즉, 클래스 내용안에 직렬화가 안 되는 객체에 대한 참조를 포함하고 있다면 transient 키워드를 붙여서 제외할 수 있습니다. 

보통 Object obj = new Object(); 의 경우 직렬화를 할 때 에러가 발생하면서 실패하는데

그 이유는 모든 객체의 최고 조상인 Object 클래스에는 Serializable 인터페이스가 구현되어있지 않기 때문입니다.

이럴 때 직렬화 하려는 클래스 내부에 해당 인스턴스 변수가 존재할 경우 아래 코드와 같이 앞에 붙여주면 직렬화 대상에서 제외됩니다.

코드로 살펴보자면, 

class Person implements java.io.Serializable {
		String name;
		int age;

		transient Object obj = new Object();
}

이렇게 간단하게 붙여주면 끝납니다! 

추가적으로 만약 Object obj = new String(”abc”); 로 하게 될 경우에는 직렬화가 가능해집니다. 

저장된 객체가 Object 가 아닌 String 인스턴스이기 때문이에요. 

인스턴스변수의 타입이 아닌 실제로 연결된 객체의 종류에 의해서 결정된다는 것을 기억해 두면 좋을 것 같습니다. 

 

마무리 

 

오늘도 끝까지 봐주신 분들께 감사드립니다. 

이번 이 주제는 남궁 성 선생님의  Java 의 정석 책으로 공부하고 참고하였습니다. 

 

 

728x90

'Computer Science > Java' 카테고리의 다른 글

Array, LinkedList, ArrayList의 차이점  (2) 2023.10.24
Reflection(리플렉션) 에 대한 개념 및 단점, 그럼에도 쓰는 이유  (4) 2023.10.10
String, StringBuffer, StringBuilder의 차이  (2) 2023.09.21
'Computer Science/Java' 카테고리의 다른 글
  • Array, LinkedList, ArrayList의 차이점
  • Reflection(리플렉션) 에 대한 개념 및 단점, 그럼에도 쓰는 이유
  • String, StringBuffer, StringBuilder의 차이
is낫널
is낫널
  • is낫널
    아직은 NULL NULL 합니다
    is낫널
  • 전체
    오늘
    어제
    • 분류 전체보기 (52)
      • Computer Science (12)
        • 운영체제 (3)
        • Java (4)
        • Spring (0)
        • 네트워크 (2)
        • 자료구조 및 알고리즘 (0)
        • 데이터베이스 (1)
      • Algorithm (10)
        • BOJ & SWEA (8)
        • Programmers (0)
        • 이론 (2)
      • Project (7)
        • Team (3)
        • Personal & Toy (4)
      • 사회인 준비생 (22)
        • SSAFY (5)
        • 이직 (1)
        • TIL (14)
      • 무작정 따라해보기 (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 글쓰기
    • 태그
    • 방명록
    • 블로그 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    HTTP
    BOJ
    코딩테스트
    transiant
    백엔드
    인터럽트핸들러
    비전공자
    그림자 문제
    개발자
    LAMBDA
    개발공부
    AWS
    빈 라인
    딩코딩코
    CS지식
    자바
    Roy Fielding
    it세계의 괴물들
    Java
    파이썬
    14510 나무 높이
    백준
    백엔드 면접지식
    개발
    문자열
    backend
    카카오톡API
    CPU의 구성요소
    sw적성진단
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
is낫널
SerialVersionUID는 무엇이고 이를 선언해야 하는 이유가 무엇일까요?
상단으로

티스토리툴바