serialVersion이란UID와 그것을 사용해야 하는 이유는 무엇입니까?
Eclipse는 다음 경우에 경고를 발행합니다.serialVersionUID
가 없습니다.
직렬화 가능한 클래스 Foo가 정적 최종 serialVersion을 선언하지 않습니다.UID 필드 길이
뭐가serialVersionUID
그리고 그게 왜 중요하죠?누락된 예를 보여 주십시오.serialVersionUID
문제가 생깁니다.
에 대한 설명으로는 다음과 같은 내용을 들 수 있습니다.
시리얼라이제이션 런타임은 시리얼라이제이션이 가능한 각 클래스와 관련지어집니다.버전 번호는
serialVersionUID
시리얼화된 객체의 송신측과 수신측이 시리얼라이제이션과 관련하여 그 객체의 클래스를 로드하고 있는지 확인하기 위해 디시리얼라이제이션 중에 사용됩니다.수신기가 다른 객체에 대한 클래스를 로드한 경우serialVersionUID
대응하는 송신자 클래스의 클래스보다, 역직렬화하면, 가 됩니다.시리얼화 가능한 클래스는, 독자적인 것을 선언할 수 있습니다.serialVersionUID
라고 하는 필드를 명시적으로 선언함으로써serialVersionUID
정적, 최종, 유형이어야 합니다.long
:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
시리얼화 가능한 클래스가 명시적으로 선언하지 않는 경우
serialVersionUID
시리얼라이제이션 실행 시 디폴트가 계산됩니다.serialVersionUID
Java(TM) Object Serialization Specification에 설명된 대로 클래스의 다양한 측면에 기반한 해당 클래스의 값.단, 시리얼 가능한 모든 클래스는 명시적으로 선언할 것을 강력히 권장합니다.serialVersionUID
값, 기본값 이후serialVersionUID
계산은 컴파일러 구현에 따라 달라질 수 있는 클래스의 상세 내용에 매우 민감하기 때문에 예기치 않은 결과를 초래할 수 있습니다.InvalidClassExceptions
디시리얼라이제이션 중에.따라서 일관성을 보장하기 위해serialVersionUID
여러 자바 컴파일러 구현에 걸친 값, 직렬화 가능한 클래스는 명시적이어야 합니다.serialVersionUID
가치. 또한 명시적이어야 한다는 것을 강력히 권고한다.serialVersionUID
declarations는 가능한 한 프라이빗 수식자를 사용합니다.이는 이러한 선언이 즉시 선언하는 클래스에만 적용되기 때문입니다.serialVersionUID
필드는 상속된 구성원으로서 유용하지 않습니다.
구현을 위해 시리얼화해야 한다는 이유만으로 시리얼화를 하는 경우(시리얼화를 위해 시리얼화를 하는 경우)HTTPSession
예를 들어...저장 여부에는 관심이 없을 것입니다.de-serializing
폼 오브젝트)는 무시해도 됩니다.
실제로 직렬화를 사용하는 경우 직렬화를 사용하여 개체를 직접 저장 및 검색할 계획인 경우에만 문제가 됩니다.그serialVersionUID
는 클래스 버전을 나타냅니다.클래스의 현재 버전이 이전 버전과 하위 호환성이 없는 경우 이 버전을 늘려야 합니다.
대부분의 경우 시리얼화를 직접 사용하지 않습니다.이 경우 기본값을 생성합니다.SerialVersionUID
퀵픽스 옵션을 클릭하면 됩니다.걱정하지 마세요.
Josh Bloch의 책 Effective Java (제2판)를 홍보할 기회를 놓칠 수 없다.10장은 Java 시리얼라이제이션에 필수적인 자원입니다.
Josh에 따르면 자동으로 생성된 UID는 클래스 이름, 구현된 인터페이스 및 모든 공용 및 보호된 멤버에 기반하여 생성됩니다.이들 중 하나를 변경하면,serialVersionUID
따라서 클래스 중 하나(프로세스 간에 또는 나중에 스토리지에서 검색)만 직렬화할 수 있다고 확신할 수 있는 경우에만 이러한 문제를 해결할 필요가 없습니다.
일단 무시했다가 나중에 어떤 식으로든 클래스를 변경해야 하지만 이전 버전의 클래스와의 호환성을 유지해야 한다는 것을 알게 되면 JDK 툴시리얼 서버를 생성할 수 있습니다.serialVersionUID
(변경 내용에 따라서는 커스텀시리얼라이제이션의 실장도 필요하게 되는 경우가 있습니다).writeObject
그리고.readObject
메서드 - 참조Serializable
javadoc 또는 앞서 언급한 10장).
이클립스에게 이러한 serialVersion을 무시하도록 지시할 수 있습니다.UID 경고:
창 > [설정]> [ Java ]> [ 컴파일러 ]> [오류/경고]> [프로그래밍의 잠재적인 문제]
모르는 경우 이 섹션에서 활성화할 수 있는 경고(또는 오류로 보고되는 경고도 있음)는 매우 유용합니다.
- 잠재적인 프로그래밍 문제:우발적인 부울 할당 가능성
- 잠재적인 프로그래밍 문제:특수한 포인터 액세스
- 불필요한 코드:로컬 변수를 읽지 않음
- 불필요한 코드: 중복 null 체크
- 불필요한 코드:불필요한 캐스팅 또는 '인스턴스 오브'
더 많이요.
serialVersionUID
는 시리얼화된 데이터의 버전 관리를 용이하게 합니다.이 값은 시리얼화할 때 데이터와 함께 저장됩니다.시리얼 해제 시 시리얼화된 데이터가 현재 코드와 어떻게 일치하는지 확인하기 위해 동일한 버전이 체크됩니다.
데이터를 버전화하려면 일반적으로 다음 명령어로 시작합니다.serialVersionUID
시리얼화된 데이터를 변경하는 구조 변경 시마다 범핑합니다(비필드의 삭제 또는 삭제).
내장 디시리얼라이제이션메커니즘(in.defaultReadObject()
)는 이전 버전의 데이터로부터의 디컴라이징을 거부합니다.그러나 원하는 경우 오래된 데이터를 다시 읽을 수 있는 자체 readObject() 함수를 정의할 수 있습니다.이 커스텀 코드에 의해서, 다음의 정보를 확인할 수 있습니다.serialVersionUID
데이터가 어떤 버전인지 확인하고 데이터 디컴라이징 방법을 결정하기 위해 사용합니다.이 버전 기술은 코드의 여러 버전에서 살아남는 직렬화된 데이터를 저장하는 경우에 유용합니다.
그러나 이렇게 긴 시간 동안 직렬화된 데이터를 저장하는 것은 그리 흔한 일이 아닙니다.시리얼라이제이션메커니즘을 사용하여 데이터를 일시적으로 캐시에 쓰거나 네트워크를 통해 코드베이스의 관련 부분이 동일한 다른 프로그램으로 전송하는 것이 훨씬 일반적입니다.
이 경우 하위 호환성을 유지하는 데 관심이 없습니다.통신하고 있는 코드 베이스가 실제로 같은 버전의 관련 클래스를 가지고 있는지 확인하는 것만이 중요합니다.이러한 체크를 용이하게 하기 위해서는serialVersionUID
이전과 마찬가지로 클래스를 변경할 때 업데이트해야 합니다.
필드 갱신을 잊어버린 경우 구조는 다르지만 클래스는 같은2개의 다른 버전이 될 수 있습니다.serialVersionUID
이 경우 기본 메커니즘(in.defaultReadObject()
)는, 어떠한 차이도 검출하지 않고, 호환성이 없는 데이터의 사이즈를 해제하려고 합니다.이로 인해 크립토 런타임에러나 사일런트 에러(Null 필드)가 발생할 가능성이 있습니다.이러한 유형의 오류는 찾기 어려울 수 있습니다.
이 사용 사례를 지원하기 위해 Java 플랫폼에서는 다음 옵션을 설정하지 않아도 됩니다.serialVersionUID
수동으로 조작할 수 있습니다.대신 클래스 구조의 해시가 컴파일 시 생성되어 ID로 사용됩니다.이 메커니즘은 동일한 ID를 가진 다른 클래스 구조를 갖지 않도록 하기 때문에 위에서 설명한 추적하기 어려운 런타임시리얼라이제이션 장애가 발생하지 않습니다.
하지만 자동 생성된 ID 전략에는 이면이 있습니다.즉, 같은 클래스에 대해 생성된 ID는 컴파일러마다 다를 수 있습니다(위의 Jon Sket에서 설명).따라서 서로 다른 컴파일러로 컴파일된 코드 간에 시리얼화된 데이터를 통신할 경우 ID를 수동으로 유지하는 것이 좋습니다.
또한 처음 언급한 사용 사례에서와 같이 데이터와 하위 호환성이 있는 경우 ID를 직접 유지 관리해야 할 수도 있습니다.이를 통해 판독 가능한 ID를 취득하고 변경 시기와 방법을 보다 효과적으로 제어할 수 있습니다.
serialVersion이란UID와 그것을 사용해야 하는 이유는 무엇입니까?
SerialVersionUID
각 클래스의 고유 식별자입니다.JVM
는 클래스 버전을 비교하기 위해 이 명령을 사용하여 시리얼라이제이션 중에 사용된 것과 동일한 클래스가 디시리얼라이제이션 중에 로드되도록 합니다.
1개를 지정하면 제어력이 향상되지만 지정하지 않으면 JVM이 생성합니다.생성되는 값은 컴파일러마다 다를 수 있습니다.게다가 어떤 이유로 오래된 시리얼화된 오브젝트의 시리얼화를 금지하고 싶은 경우도 있습니다.backward incompatibility
이 경우 serialVersion을 변경하기만 하면 됩니다.UID.
의 자바독은 다음과 같습니다.
기본 serialVersionUID 계산은 컴파일러 구현에 따라 달라질 수 있는 클래스의 상세 내용에 매우 민감하기 때문에 예기치 않은 결과가 발생할 수 있습니다.
InvalidClassException
s는 디시리얼라이제이션 중에 발생합니다.
따라서 serialVersion을 선언해야 합니다.UID는 우리에게 더 많은 통제력을 주기 때문입니다.
이 기사는 그 주제에 대해 몇 가지 좋은 점을 가지고 있다.
첫 번째 질문은 '왜 중요한가'와 '예시'를 묻는 질문입니다.Serial Version ID
도움이 될 것 같아요음, 하나 찾았어요.
작성한다고 합시다.Car
클래스, 인스턴스화 및 오브젝트 스트림에 씁니다.납작한 자동차 물체는 한동안 파일 시스템에 보관됩니다.한편, 만약Car
클래스는 새 필드를 추가하여 변경합니다.나중에 평평한 부분을 읽으려고 할 때(즉, 역직렬화)Car
오브젝트, 당신은java.io.InvalidClassException
– 시리얼 가능한 모든 클래스에 고유 식별자가 자동으로 지정되기 때문입니다.이 예외는 클래스의 식별자가 평탄한 객체의 식별자와 동일하지 않을 때 느려집니다.실제로 생각해 보면 새 필드가 추가되었기 때문에 예외가 발생합니다.명시적인 serialVersion을 선언함으로써 버전 관리를 직접 제어함으로써 이 예외가 발생하는 것을 방지할 수 있습니다.UID입니다. 또한 명시적으로 선언하는 것은 작은 퍼포먼스상의 이점이 있습니다.serialVersionUID
(계산할 필요가 없기 때문에).따라서 serialVersion을 직접 추가하는 것이 좋습니다.UID를 Serializable 클래스로 만듭니다.
public class Car {
static final long serialVersionUID = 1L; //assign a long value
}
먼저 일련번호가 무엇인지 설명할 필요가 있습니다.
직렬화를 통해 개체를 스트림으로 변환하여 네트워크를 통해 개체를 전송하거나, 파일에 저장하거나, 문자를 사용할 수 있도록 DB에 저장할 수 있습니다.
시리얼라이제이션에는 몇 가지 규칙이 있습니다.
오브젝트는 클래스 또는 그 슈퍼클래스가 Serializable 인터페이스를 구현하는 경우에만 Serializable이 가능합니다.
오브젝트는 슈퍼클래스가 시리얼화되지 않은 경우에도 시리얼화 가능합니다(시리얼화 가능한 인터페이스를 실장합니다).단, Serializable 인터페이스를 구현하지 않는 Serializable 클래스의 계층 내 첫 번째 슈퍼클래스에는 no-arg 컨스트럭터가 필요합니다.이를 위반할 경우 readObject()는 java.io를 생성합니다.런타임의 비활성 ClassException
모든 기본 유형은 직렬화할 수 있습니다.
과도 필드(과도적 수식자 포함)는 직렬화되지 않습니다(즉, 저장되거나 복원되지 않음).Serializable을 구현하는 클래스는 직렬화를 지원하지 않는 클래스의 임시 필드(예: 파일 스트림)를 표시해야 합니다.
스태틱 필드(스태틱 수식자 포함)는 시리얼화되지 않습니다.
언제Object
시리얼화 되고 Java Runtime은 시리얼 버전 번호(일명 'ka')를 관련짓습니다.serialVersionID
.
serial Version이 필요한 경우아이디:
디시리얼라이제이션중에, 송신자와 수신자가 시리얼라이제이션에 관해서 호환성이 있는 것을 확인합니다.수신자가 다른 클래스로 로드한 경우serialVersionID
디시리얼라이제이션은 다음과 같이 종료됩니다.InvalidClassCastException
.
직렬화 가능한 클래스는 자체 클래스임을 선언할 수 있습니다.serialVersionUID
라고 하는 필드를 명시적으로 선언함으로써serialVersionUID
정적이고 최종적이며 긴 유형이어야 합니다.
예를 들어 보겠습니다.
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;
public String getEmpName() {
return name;
}
public void setEmpName(String empname) {
this.empname = empname;
}
public byte getEmpAge() {
return empage;
}
public void setEmpAge(byte empage) {
this.empage = empage;
}
public String whoIsThis() {
return getEmpName() + " is " + getEmpAge() + "years old";
}
}
시리얼라이즈 오브젝트 작성
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
Employee employee = new Employee();
employee.setEmpName("Jagdish");
employee.setEmpAge((byte) 30);
FileOutputStream fout = new
FileOutputStream("/users/Jagdish.vala/employee.obj");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(employee);
oos.close();
System.out.println("Process complete");
}
}
개체를 역직렬화합니다.
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Employee employee = new Employee();
FileInputStream fin = new FileInputStream("/users/Jagdish.vala/employee.obj");
ObjectInputStream ois = new ObjectInputStream(fin);
employee = (Employee) ois.readObject();
ois.close();
System.out.println(employee.whoIsThis());
}
}
메모: serialVersion을 변경합니다.Employee 클래스의 UID 및 저장:
private static final long serialVersionUID = 4L;
Reader 클래스를 실행합니다.Writer 클래스를 실행하지 않으면 예외가 발생합니다.
Exception in thread "main" java.io.InvalidClassException:
com.jagdish.vala.java.serialVersion.Employee; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)
오브젝트를 바이트 어레이에 시리얼화하여 송신/저장할 필요가 없다면 걱정할 필요가 없습니다.이 경우 serialVersion을 고려해야 합니다.오브젝트의 역직렬화기는 클래스 로더가 가지고 있는 오브젝트의 버전과 일치하기 때문에 UID.자세한 내용은 Java Language Specification을 참조하십시오.
수업시간에 이 경고를 받으면 시리얼화할 생각은 전혀 하지 않고 자신을 선언하지도 않았습니다.implements Serializable
많은 경우 Serializable을 구현하는 슈퍼클래스에서 상속받았기 때문입니다.종종 상속을 사용하는 대신 이러한 개체에 위임하는 것이 좋습니다.
그래서 대신
public class MyExample extends ArrayList<String> {
public MyExample() {
super();
}
...
}
하다
public class MyExample {
private List<String> myList;
public MyExample() {
this.myList = new ArrayList<String>();
}
...
}
그리고 관련 방법으로 전화한다.myList.foo()
대신this.foo()
(또는super.foo()
(이것은 모든 경우에 적합한 것은 아니지만, 그래도 꽤 자주 발생합니다.)
JFrame 같은 것을 굳이 위임만 하면 되는 사람을 자주 볼 수 있습니다.(JFrame에는 수백 개의 메서드가 있기 때문에 클래스의 커스텀 메서드를 호출할 때 필요하지 않기 때문에 IDE에서 자동 완료에도 도움이 됩니다).
이 경고(또는 serialVersion)가UID)는 AbstractAction(일반적으로 익명 클래스)에서 actionPerformed-method만 추가하는 경우 피할 수 없습니다.이 경우 경고는 있을 수 없다고 생각합니다(일반적으로 이러한 익명의 클래스는 다른 버전의 클래스에서 serialize 및 deserialize 할 수 없기 때문에). 하지만 컴파일러가 이를 어떻게 인식할 수 있었는지 모르겠습니다.
serialVersion 필드의 중요성을 이해하려면UID, 시리얼화/디시리얼라이제이션의 구조를 이해할 필요가 있습니다.
Serializable 클래스 오브젝트가 시리얼화되면 Java Runtime은 시리얼 버전 번호(serialVersion이라고 불립니다)를 관련짓습니다.UID)를 지정합니다.이 시리얼화된 오브젝트의 시리얼화를 해제할 때 Java Runtime은 serialVersion과 일치합니다.serialVersion을 사용하는 시리얼화된 객체의 UID클래스의 UID양쪽이 같으면 디시리얼라이제이션의 추가 프로세스만 진행되며, 그렇지 않으면 Invalid Class Exception이 느려집니다.
따라서 serialization/deserialization 프로세스를 성공시키기 위해서는 serialVersion이 필요합니다.직렬화된 개체의 UID는 serialVersion과 같아야 합니다.클래스의 UID프로그래머가 serialVersion을 지정한 경우프로그램에서 명시적으로 UID 값을 지정하면 시리얼라이제이션 및 디시리얼라이제이션 플랫폼에 관계없이 동일한 값이 시리얼라이제이션 객체 및 클래스에 관련지어집니다(예를 들어 시리얼라이제이션은 Sun 또는 MS JVM을 사용하여 Windows와 같은 플랫폼에서 실행되며 디시리얼라이제이션은 Zing JVM을 사용하여 다른 플랫폼 Linux에서 수행될 수 있습니다).
단, serialVersion이UID는 프로그래머에 의해 지정되지 않으며 오브젝트의 Serialization\DeSerialization을 실행하는 동안 Java 런타임은 자체 알고리즘을 사용하여 계산합니다.이 시리얼 버전UID 계산 알고리즘은 JRE마다 다릅니다.또, 오브젝트가 시리얼화되는 환경에서는 1개의 JRE(예: SUN JVM)를 사용하고 있어, 디세리얼라이제이션이 발생하는 환경에서는 Linux Jvm(zing)을 사용하고 있을 수 있습니다.이 경우 serialVersion직렬화된 개체와 연결된 UID가 serialVersion과 다릅니다.탈직렬 환경에서 계산된 클래스의 UID입니다.결과적으로 역직렬화는 성공하지 못할 것입니다.따라서 이러한 상황/문제를 피하기 위해 프로그래머는 항상 serialVersion을 지정해야 합니다.Serializable 클래스의 UID.
예를 들어 serialVersion이 누락되어 있는 경우UID로 인해 문제가 발생할 수 있습니다.
웹 모듈로 구성된 Java EE 어플리케이션에서 작업하고 있습니다.EJB
모듈.웹 모듈은EJB
리모트 모듈 및 패스POJO
을 구현합니다.Serializable
의론으로서.
이것.POJO's
클래스는 EJB jar 내부와 웹 모듈의 WEB-INF/lib에 있는 자체 jar 내부에 패키지되어 있습니다.실제로는 같은 클래스이지만, EJB 모듈을 포장할 때는 이 POJO의 병을 풀어서 EJB 모듈과 함께 포장합니다.
에의 콜EJB
아래 예외에서 실패했다고 선언하지 않았기 때문에serialVersionUID
:
Caused by: java.io.IOException: Mismatched serialization UIDs : Source
(Rep.
IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588)
= 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52)
= 6227F23FA74A9A52
디폴트 계산은 99,9999%의 케이스로 충분합니다.또, 문제가 발생했을 경우는, 이미 말한 대로, 필요에 따라서 UID 를 도입할 수 있습니다(그럴 가능성은 거의 없습니다).
저는 보통serialVersionUID
다음 중 하나의 컨텍스트:Java VM의 컨텍스트를 벗어나는 것을 알고 있는 경우.
이걸 쓰면 알 수 있을 것 같아ObjectInputStream
그리고.ObjectOutputStream
어플리케이션이나 사용하는 라이브러리/프레임워크를 알고 있는 경우 사용합니다.serial Version(시리얼 버전)ID를 통해 다양한 버전의 다양한 Java VM 또는 벤더가 올바르게 상호 운용하거나 VM 외부에 저장 및 취득할 수 있습니다.HttpSession
세션 데이터는 응용 프로그램서버의 재시작 및 업그레이드 중에도 유지됩니다.
다른 모든 경우, 저는
@SuppressWarnings("serial")
대부분의 경우 디폴트이기 때문에serialVersionUID
충분합니다.여기에는 다음이 포함됩니다.Exception
,HttpServlet
.
필드 데이터는 클래스에 저장된 일부 정보를 나타냅니다.클래스는Serializable
이클립스가 자동으로 선언하도록 제공되었습니다.serialVersionUID
field. 값 1부터 시작합니다.
경고를 표시하지 않으려면 다음을 사용하십시오.
@SuppressWarnings("serial")
시리얼 버전UID는 오브젝트 버전 제어에 사용됩니다.serialVersion을 지정할 수 있습니다.클래스 파일에도 UID가 있습니다.serialVersion을 지정하지 않은 결과UID는 serialVersion으로 인해 클래스 내의 필드를 추가하거나 변경할 때 이미 시리얼화된 클래스는 복구할 수 없습니다.새 클래스에 대해 생성된 UID와 이전 직렬화된 개체에 대해 생성된 UID가 다릅니다.Java 시리얼화 프로세스는 올바른 serialVersion에 의존합니다.시리얼화된 객체의 상태를 회복하기 위한 UID로 java.io을 슬로우합니다.serialVersion의 경우 비활성 ClassExceptionUID 불일치
상세내용 : http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ
사용하는 이유SerialVersionUID
안에서.Serializable
자바어 수업?
동안serialization
Java 런타임은 클래스 버전 번호를 생성하여 나중에 시리얼을 해제할 수 있도록 합니다.이 버전 번호는 다음과 같습니다.SerialVersionUID
자바어.
SerialVersionUID
는 시리얼화된 데이터의 버전에 사용됩니다.클래스의 시리얼화를 해제할 수 있는 것은, 다음과 같은 경우 뿐입니다.SerialVersionUID
는 시리얼화된 인스턴스와 일치합니다.우리가 선언하지 않을 때SerialVersionUID
클래스에서는 Java 런타임에 의해 생성되지만 권장되지는 않습니다.신고할 것을 권장합니다.SerialVersionUID
~하듯이private static final long
variable을 지정하면 디폴트메커니즘을 클릭합니다.
클래스를 선언할 때Serializable
마커 인터페이스를 구현하여java.io.Serializable
를 사용하여 프로세스를 커스터마이즈하지 않은 경우 기본 시리얼라이제이션메커니즘을 사용하여 해당 클래스의 Java 런타임 퍼시스턴스를 디스크에 저장합니다.Externalizable
인터페이스입니다.
참고 항목: SerialVersion을 사용하는 이유Java의 Serializable 클래스 내 UID
CheckStyle을 통해 serialVersion이 다음과 같이 설정되어 있는지 확인할 수 있으면 좋겠습니다.Serializable을 구현하는 클래스의 UID는 시리얼 버전 ID 생성기와 일치하는 우수한 값을 가집니다.예를 들어 기존 serialVersion을 삭제하는 등 시리얼 가능한 DTO가 많은 프로젝트가 있는 경우UID를 재생성하는 것은 귀찮은 일이며, 현재 이것을 확인할 수 있는 유일한 방법은 클래스별로 재생성하여 기존과 비교하는 것입니다.이것은 매우 매우 고통스럽다.
serialVersion이 없었던 대량의 클래스를 수정하는 경우UID는 기존 클래스와의 호환성을 유지하면서 설정되지만 IntelliJ Idea, Eclipse 등의 툴은 랜덤한 번호를 생성하기 때문에 부족하며 다수의 파일을 한꺼번에 처리할 수 없습니다.serialVersion을 수정하기 위해 다음 bash 스크립트(Windows 사용자에게 죄송합니다.Mac을 구입하거나 Linux로 변환하는 것을 검토하십시오)가 표시됩니다.UID 문제:
base_dir=$(pwd)
src_dir=$base_dir/src/main/java
ic_api_cp=$base_dir/target/classes
while read f
do
clazz=${f//\//.}
clazz=${clazz/%.java/}
seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//')
perl -ni.bak -e "print $_; printf qq{%s\n}, q{ private $seruidstr} if /public class/" $src_dir/$f
done
이 스크립트를 저장합니다(add_serialVersion 등).UID.sh ~/bin.그런 다음 Maven 또는 Gradle 프로젝트의 루트 디렉토리에서 다음과 같이 실행합니다.
add_serialVersionUID.sh < myJavaToAmend.lst
이 .lst에는 serialVersion을 추가하기 위한 Java 파일 목록이 포함되어 있습니다.다음 형식의 UID:
com/abc/ic/api/model/domain/item/BizOrderTransDO.java
com/abc/ic/api/model/domain/item/CardPassFeature.java
com/abc/ic/api/model/domain/item/CategoryFeature.java
com/abc/ic/api/model/domain/item/GoodsFeature.java
com/abc/ic/api/model/domain/item/ItemFeature.java
com/abc/ic/api/model/domain/item/ItemPicUrls.java
com/abc/ic/api/model/domain/item/ItemSkuDO.java
com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java
com/abc/ic/api/model/domain/serve/ServeFeature.java
com/abc/ic/api/model/param/depot/DepotItemDTO.java
com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java
com/abc/ic/api/model/param/depot/InDepotDTO.java
com/abc/ic/api/model/param/depot/OutDepotDTO.java
이 스크립트에서는 후드 아래의 JDK serialVer 도구를 사용합니다.그러니까 JAVA를 꼭...HOME/bin은 PATH에 있습니다.
이 질문은 Joshua Bloch의 Effective Java에서 매우 잘 문서화되어 있습니다.아주 좋은 책이자 꼭 읽어야 할 책이다.그 이유의 개요를 이하에 나타냅니다.
시리얼라이제이션 런타임에는 시리얼화 가능한 클래스별로 시리얼버전이라고 불리는 번호가 표시됩니다.이 번호를 serialVersion이라고 부릅니다.UID. 이 숫자 뒤에 수학이 있으며 클래스에 정의된 필드/메서드에 따라 표시됩니다.같은 클래스에 대해 매번 같은 버전이 생성됩니다.이 번호는 시리얼라이제이션 중에 시리얼라이제이션과 관련하여 시리얼라이제이션된 객체의 송신측과 수신측이 해당 객체의 클래스를 로드하고 있는지 확인하기 위해 사용됩니다.수신자가 serialVersion이 다른 객체의 클래스를 로드한 경우대응하는 송신자 클래스의 UID보다 큰 UID로, 역직렬화하면 Invalid Class Exception이 됩니다.
클래스가 시리얼 가능한 경우 serialVersion을 선언할 수도 있습니다."serialVersion"이라는 이름의 필드를 명시적으로 선언하여 UID를 지정합니다.UID"는 정적, 최종, 긴 타입이어야 합니다.대부분의 IDE는 Eclipse와 같은 기능을 통해 긴 문자열을 생성할 수 있습니다.
개체가 직렬화될 때마다 개체 클래스에 대한 버전 ID 번호가 개체에 스탬프로 표시됩니다.이 ID를 serialVersion이라고 합니다.UID는 클래스 구조에 대한 정보를 기반으로 계산됩니다.Employee 클래스를 만들고 버전 ID #333(JVM에 의해 할당됨)을 가지고 있다고 가정합니다.이 클래스의 오브젝트를 시리얼화하면(Supply Employee 오브젝트), JVM은 UID를 #333으로 할당합니다.
상황을 생각해 보십시오.앞으로 클래스를 편집 또는 변경해야 합니다.이 경우 클래스를 수정하면 JVM에 의해 새로운 UID(가정 #444)가 할당됩니다.종업원 오브젝트를 역직렬화하려고 하면 JVM은 시리얼화된 오브젝트의 (Employe 오브젝트)버전 ID(#333)를 클래스 버전 ID(예: #444)와 비교합니다(변경 후).비교 결과 JVM은 두 버전 UID가 다르므로 역직렬화가 실패합니다.따라서 serialVersion이각 클래스의 ID는 프로그래머 자체에 의해 정의됩니다.앞으로 클래스가 진화해도 동일하기 때문에 JVM은 클래스가 변경되어도 클래스가 시리얼화된 오브젝트와 호환성이 있다는 것을 항상 알게 됩니다.자세한 내용은 HEAD FIRST JAVA의 14장을 참조하십시오.
간단한 설명:
데이터를 직렬화하고 있습니까?
시리얼화는 기본적으로 클래스 데이터를 파일/스트림 등에 쓰는 것입니다.디시리얼라이제이션이란, 그 데이터를 클래스로 읽어내는 것입니다.
생산에 들어갈 생각입니까?
중요하지 않은 데이터나 가짜 데이터를 사용하여 테스트하는 경우라면 걱정할 필요가 없습니다(직접 시리얼화를 테스트하지 않는 한).
이게 첫 번째 버전인가요?
이 경우 설정
serialVersionUID=1L
.이것이 두 번째, 세 번째, 기타 제품 버전입니까?
이제 걱정해야 할 건
serialVersionUID
상세하게 조사해야 합니다.
기본적으로 쓰기/읽기가 필요한 클래스를 업데이트할 때 버전을 올바르게 업데이트하지 않으면 이전 데이터를 읽으려고 할 때 오류가 발생합니다.
'시리얼 버전'UID'는 역직렬화 프로세스 중에 클래스를 일의로 식별하기 위해 사용되는 64비트 번호입니다.개체를 직렬화할 때 serialVersion클래스 UID도 파일에 입력됩니다.이 개체를 역직렬화할 때마다 Java 런타임에 의해 이 serialVersion이 추출됩니다.시리얼화된 데이터의 UID 값을 사용하여 클래스에 관련된 동일한 값을 비교합니다.둘 다 일치하지 않으면 java.io을 참조하십시오.Invalid Class Exception'이 느려집니다.
serialable 클래스가 serialVersion을 명시적으로 선언하지 않은 경우UID에서 시리얼라이제이션 실행 시 serialVersion이 계산됩니다.필드, 메서드 등 클래스의 다양한 측면에 기반한 해당 클래스의 UID 값... 데모 응용 프로그램에 대해서는 이 링크를 참조하십시오.
먼저 Serial Version을 선언하지 않은 경우 질문에 답합니다.클래스 내의 UID는 Java 런타임에 의해 생성됩니다만, 이 프로세스는 필드 수, 필드 유형, 필드의 액세스 수식자, 클래스별로 구현된 인터페이스 등을 포함한 많은 클래스 메타 데이터에 민감합니다.따라서 우리가 직접 선언하는 것이 좋으며 이클립스도 이에 대해 경고하고 있습니다.
시리얼화:대부분의 경우 오브젝트 상태를 다른 머신으로 전송할 때 전원/시스템 장애(또는 네트워크 장애)로 인해 상태가 손실될 위험이 없는 중요한 오브젝트(개체 변수 내의 데이터)를 취급합니다.이 문제의 해결 방법은 단순히 데이터를 유지(유지/저장)하는 것을 의미하는 "지속성"이라고 합니다.시리얼라이제이션은 (데이터를 디스크/메모리에 저장함으로써) 지속성을 실현하는 다른 많은 방법 중 하나입니다.오브젝트 상태를 저장할 때는 오브젝트의 ID를 생성하여 올바르게 읽을 수 있도록 하는 것이 중요합니다(시리얼라이제이션 해제).이 고유 ID는 ID는 SerialVersion입니다.UID.
요약하자면, 이 필드는 직렬화된 데이터를 올바르게 역직렬화할 수 있는지 확인하는 데 사용됩니다.시리얼라이제이션과 디시리얼라이제이션은 보통 프로그램의 다른 복사본에 의해 이루어집니다.예를 들어 서버는 오브젝트를 문자열로 변환하고 클라이언트는 수신한 문자열을 오브젝트로 변환합니다.이 필드는 이 객체가 무엇인지에 대해 양쪽이 동일한 생각으로 작동함을 나타냅니다.이 필드는 다음 경우에 도움이 됩니다.
다른 장소(예: 서버 1대 및 클라이언트 100대)에 프로그램의 여러 복사본을 가지고 있습니다.오브젝트 변경, 버전 번호 변경, 이 클라이언트의 갱신을 잊은 경우, 그는 역직렬화 할 수 없다는 것을 알 수 있습니다.
데이터를 일부 파일에 저장했다가 나중에 변경된 개체로 업데이트된 버전의 프로그램으로 열려고 합니다. 올바른 버전을 유지하면 이 파일은 호환되지 않습니다.
언제가 중요합니까?
가장 분명한 것은 일부 필드를 개체에 추가하면 이전 버전의 개체 구조에는 이러한 필드가 없기 때문에 이러한 필드를 사용할 수 없다는 것입니다.
명확하지 않음 - 개체를 역직렬화하면 문자열에 없는 필드는 NULL로 유지됩니다. 개체에서 필드를 삭제한 경우 이전 버전은 이 필드를 allways-NULL로 유지하며, 이전 버전은 이 필드의 데이터에 의존할 경우 잘못된 동작을 일으킬 수 있습니다.
가장 명확하지 않음 - 때때로 당신은 당신이 어떤 분야의 의미에 넣었던 생각을 바꿀 수 있습니다.예를 들어, 당신이 12살일 때는 "자전거"라는 의미로 "자전거"를 의미하지만, 당신이 18살일 때는 "자전거를 타고 도시를 횡단하라"는 뜻으로 당신을 초대한다면, 당신은 자전거를 타고 온 유일한 사람이 될 것이고, 당신은 들판에서 같은 의미를 유지하는 것이 얼마나 중요한지 짐작할 수 없을 것이다:-)
Serial Version이란UID? 답변: HQ와 ODC에서 각각 시리얼라이제이션과 디시리얼라이제이션이 실행된다고 칩니다.이 경우 ODC에 있는 수신기가 인증된 사용자임을 인증하기 위해 JVM은 SerialVersion이라고 하는 고유 ID를 만듭니다.UID.
여기 시나리오에 근거한 좋은 설명이 있습니다.
시리얼 버전이 필요한 이유UID?
Serialization : 시리얼라이제이션 시 모든 오브젝트 송신측에서 JVM이 Unique Identifier를 저장합니다.JVM은 발신자 시스템에 존재하는 대응하는 .class 파일을 기반으로 고유한 ID를 생성합니다.
역직렬화:역직렬화 시 리시버 측 JVM은 객체에 관련된 고유 ID를 로컬 클래스 고유 ID와 비교합니다.즉, JVM은 리시버 시스템에 존재하는 대응하는 .class 파일을 기반으로 고유 ID를 만듭니다.양쪽의 일의 ID가 일치하면, 역직렬화만이 실행됩니다.그렇지 않으면 Invalid Class Exception이라고 하는 런타임 예외가 표시됩니다.이 고유 식별자는 SerialVersion에 불과합니다.UID
언급URL : https://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it
'programing' 카테고리의 다른 글
정확한 브라우저 이름과 버전을 얻는 방법 (0) | 2022.09.18 |
---|---|
어레이가 비어 있는지 없는지 확인하는 방법 (0) | 2022.09.17 |
도커 파일에 mariaDB 베이스를 구축할 수 없습니다. (0) | 2022.09.17 |
PHP에서 JavaScript로 JSON을 반환하시겠습니까? (0) | 2022.09.17 |
Python으로 이메일 보내는 방법 (0) | 2022.09.17 |