데이타의 전송은 객체건 뭐건 결국 바이트의 흐름으로 전송하게 된다. 저장도 그렇고...
다시 읽었을 때 객체의 자료구조를 그대로 보존하지 않으면 않된다.(일명 Serialzation)
자바에선 Serializable 인터페이스만 구현하면 알아서 이를 보장해주기에 단지 implements Serializable 만 추가하면 된다.
 
일전에도 언급한 적이 있지만 5.0 이후부터는 Serialzable 인터페이스를 구현한 클래스에서
 static final long 타입의 serialVersionUID 상수를 선언하라는 경고문구를 
이클립스의 노란 warning 아이콘과 더불어 확인 할 수 있다.
 
만일 serialVersionUID를 지정하지 않으면 실행시점에서 JVM이 디폴트 값을 산정하게 되며, 
그 알고리즘은 Java(TM) Object Serialization Specification 정의된 것을 따른다고 한다. 
한마디로 굳이 신경 쓸필요는 없다는 뜻이고 이클립스내에서 이 경고아이콘을 제외하도록 설정할 수도 있다.
 
그러나 모든 serialization이 필요한 클래스에는 명시적으로 serialVersionUID를 선언해줄것을 강력하게 권유하고 있는데 
그 이유는  디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에 컴파일러 구현체에 따라서 달라질 수 있어 deserialization(serialization 했던 객체를 복구하는 과정)과정에서 예상하지 못한 InvalidClassExceptions을 유발할 수 있다.
라는 것이 그 이유란다.
 
즉 서로 다른 자바 컴파일러 구현체 사이에서도 동일한 serialVersionUID값을 얻기 위해서는 명시적으로 serialVersionUID값을 선언해야 하며 가능한 serialVersionUID을 private으로 선언하라는 것이다.
(상속되어 쓰여지는 것은 유용하지 않고, 해당 클래스에서만 쓰일 것이기 때문에....)
 
이궁 이렇게 이야기하는데 한줄 더 써주지 머...
ㅋ 말은 이리 하지만 무진장 귀찮다. serialver.exe를 이용하면 된다는데 다른 건 없나 찾아보게 되었다
 
첨부파일을 압축을 풀고 이클립스 플러그인 디렉토리에 넣어두면 자동생성 플러그인 설치는 끝
3.3에서도 이상없이 작동한다. 사용방법은 다음과 같다.
파일을 선택 마우스 오른클릭하면
Add serialVersionUID 라는 메뉴가 추가 되어 있는것을 확인할 수 있다.

 

 

그러면 다음과 같이 클래스에 serialVersionUID가 자동 생성되었슴을 확인할 수 있다.

간단히 private 만 적어주면 끝...

 

 

 

 

 

 


serialversionutil-civan.zip



 
출처 - http://blog.daum.net/yellowjini/5216095







serialVersionUID 기본 알고리즘

자바에서 serial version uid를 생성하는 것은 기본적으로 서로 다른 클래스들 간의 구별을 하기 위한 것이다.

동일한 이름을 가진 클래스라 하더라도 메소드나 필드가 다를 경우 서로 다른 것으로 인식하는 것이 기본이기 때문에 Object Serialization을 할 때 import/export 등에서 버전에 따라 종종 불일치 에러가 발생하는 것을 만나게 된다.


클래스가 바뀌었다는 것을 기본 serial version uid 계산 알고리즘을 통해서 검출했기 때문이다.

물론

private static final long serialVersionUID = -6120832682080437368L;

와 같이 클래스에 직접 serial version uid 값을 지정해버리면 기본 uid 계산 알고리즘을 사용하지 않고 이 값을 사용하게 되므로 버전에 따른 불일치 에러는 막을 수 있다.


이렇게 하지 않은 경우 사소한 메소드 시그너처 변경으로도 불일치가 발생하게 된다.


기본 uid 값 계산에 사용되는 정보들은 다음과 같다.


1. 클래스 이름 (fully qualified)

2. 클래스의 접근 제한자 (public, final, abstract, 또 interface 여부)

3. 각 멤버 필드의 시그너처 (이름과 접근 제한자, 타입)

4. 각 멤버 메소드의 시그너처 (이름과 접근 제한자, 각 인자별 정보, 리턴 타입)

4. 각 생성자의 시그너처 (접근 제한자, 각 인자별 정보)

5. static initializer block 존재 유무


이러한 값들을 사용하여 적당한 문자열을 만든 다음 SHA 알고리즘을 사용하여 해시값을 계산한 값이 기본 UID 값이 된다.

이때 필드나 메소드, 생성자의 선언 순서는 바뀌더라도 상관없도록 sort를 한다음 계산을 한다.


여기에서 알 수 있듯이 사소한 변경만으로도 기본 suid 값은 변경되게 마련이다.

따라서 serializable 객체로 객체 통신에 사용되는 클래스들은 가능하면 명시적으로 suid 값을 지정해주는 것이 버전 관리의 문제를 피할 수 있는 가장 깨끗한 방법이다.


출처 - http://logonjava.blogspot.kr/2006/05/serialversionuid.html






static final long 타입의 serialVersionUID 상수를 선언하라는 경고문의 이유는...

 

Serializable 인터페이스 이외의 경우에도 보안 등의 용도로 많이 쓰였다. 일종의 객체에 대한 지문(fingerprint)으로 이해할 수 있을 것 같다. ... Serializable 인터페이스를 구현한 클래스는 자신의 serialVersionUID를 명시적으로 선언할 수 있는데, 필드의 이름은 "serialVersionUID"이며, static, final 이어야 하며 long 타입이다.

 

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

 

만일 serialVersionUID를 지정하지 않으면 실행시점에서 serialization을 담당하는 모듈이 디폴트 값을 산정하게 되며, 그 알고리즘은 Java(TM) Object Serialization Specification 정의된 것을 따른다.

 

그러나 모든 serialization이 필요한 클래스에 명시적으로 serialVersionUID 값을 선언해줄 것을 강력하게 권유한다.

 

그 이유는 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에 컴파일러 구현체에 따라서 달라질 수 있어 deserialization(serialization 했던 객체를 복구하는 과정)과정에서 예상하지 못한 InvalidClassExceptions을 유발할 수 있다.

 

그러므로, 서로 다른 자바 컴파일러 구현체 사이에서도 동일한 serialVersionUID 값을 얻기 위해서는 명시적으로 serialVersionUID 값을 선언해야 한다.

 

가능한 serialVersionUID을 private으로 선언하기를 권장한다. 상속되어 쓰여지는 것은 유용하지 않고, 해당 클래스에서만 쓰일 것이기 때문이다.

 

출처 : http://blog.empas.com/flag2ejb/read.html?a=7280070
참고 : http://www.javastudy.co.kr/docs/techtips/000229.html






'Development > Java' 카테고리의 다른 글

system.out 출력 포맷  (0) 2013.01.31
java - CRC32 클래스  (0) 2013.01.31
RSA java 구현  (0) 2012.12.26
javax.crypto.BadPaddingException: Given final block not properly padded  (0) 2012.12.24
proguard  (0) 2012.12.09
Posted by linuxism
,