최근에 Java의 기본 지식을 편집했으며 Java 직렬화 및 사제화에 대한 정보가 자세히 정리되었습니다. 이 기사를 읽는 친구들도 도움이되기를 바라면서 여기에서 메모 할 것입니다.
1. 직렬화 및 사제화의 개념
객체를 일련의 바이트 시퀀스로 변환하는 과정을 객체의 직렬화라고합니다.
바이트 시퀀스를 물체로 복원하는 과정을 물체의 사막화라고합니다.
객체의 직렬화를위한 두 가지 주요 용도가 있습니다.
1) 하드 디스크에 바이트 시퀀스를 영구적으로 저장, 일반적으로 파일에 저장합니다.
2) 바이트의 객체 시퀀스를 네트워크에서 전송합니다.
많은 응용 분야에서 특정 객체는 직렬화되어야하므로 메모리 공간을 떠나 장기 스토리지를 위해 물리적 하드 드라이브로 이동합니다. 예를 들어, 가장 일반적인 것은 웹 서버의 세션 객체입니다. 10 만 명의 사용자가 동시에 액세스 할 때 10 만 세션 객체가 나타날 수 있으며 메모리가 참을 수 없을 수 있습니다. 따라서 웹 컨테이너는 먼저 일부 시점을 하드 디스크로 직렬화 한 다음 사용될 때까지 기다린 다음 하드 디스크에 저장된 물체를 메모리에 복원합니다.
두 프로세스가 원격으로 전달되는 경우 다양한 유형의 데이터를 서로 보낼 수 있습니다. 어떤 유형의 데이터가 있든, 이진 시퀀스 형태로 네트워크에서 전송됩니다. 발신자는 네트워크에서 전송되기 위해이 Java 객체를 일련의 바이트로 변환해야합니다. 수신기는 바이트를 Java 객체로 복원해야합니다.
2. JDK 클래스 라이브러리의 직렬화 API
java.io.objectoutputStream은 객체 출력 스트림을 나타냅니다. writeObject (object obj) 메소드는 매개 변수로 지정된 OBJ 객체를 직렬화하고 얻어진 바이트 시퀀스를 대상 출력 스트림에 쓸 수 있습니다.
java.io.objectinputstream은 객체 입력 스트림을 나타냅니다. readObject () 메소드는 소스 입력 스트림에서 바이트 시퀀스를 읽고 객체로 삼아 버리고 반환합니다.
직렬화 가능하고 외부화 가능한 인터페이스를 구현하는 클래스의 객체 만 직렬화 될 수 있습니다. 외부화 가능한 인터페이스는 직렬화 가능한 인터페이스에서 상속됩니다. 외부화 가능한 인터페이스를 구현하는 클래스는 직렬화 동작을 완전히 제어하는 반면, 직렬화 가능한 인터페이스 만 구현하는 클래스는 기본 직렬화 방법을 채택 할 수 있습니다.
객체 직렬화에는 다음 단계가 포함됩니다.
1) 파일 출력 스트림과 같은 다른 유형의 대상 출력 스트림을 감싸 수있는 객체 출력 스트림을 만듭니다.
2) 객체 출력 스트림의 writeObject () 메소드를 통해 객체를 작성하십시오.
물체를 제조하는 단계는 다음과 같습니다.
1) 파일 입력 스트림과 같은 다른 유형의 소스 입력 스트림을 감싸는 객체 입력 스트림을 만듭니다.
2) 객체 입력 스트림의 readObject () 메소드를 통해 객체를 읽습니다.
객체 직렬화 및 desequencing 예제 :
직렬화 가능한 인터페이스를 구현하기 위해 개인 클래스를 정의하십시오
1 import java.io.serializable; 2 3 /** 4 * <p> ClassName : Person <P> 5 * <p> 설명 : 테스트 객체 직렬화 및 사막화 <P> 6 * @Audp 7 * @version 1.0 V 8 * @CreateTime 2014-6-9 02:25 PM 9 * /10 공공 수업 인사 시리얼 리화 가능 {11 12 /** 13 * /15 Serialization id14 * /15 PRICETION SerialVersionUID = -580978257827294399L; 16 개인 int 연령; 17 개인 문자열 이름; 18 개인 문자열 이름; 19 20 public int getage () {21 Return Age; 22} 23 24 Public String getName () {25 반환 이름; 26 Public String getSex () {29 retoy; 30} 31 33 33 33 Age; 34} 35 36 Public void setName (문자열 이름) {37 this.name = 이름; 38} 39 40 Public Void SetSex (String Sex) {41 this.sex = sex; 42} 43}사람 클래스 객체를 직렬화하고 실질화합니다
import java.io.file; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.fileoutputStream; import java.io.ioexception; import java.io.ObjectInputStream; import java.io.objectPutStream; import java.text.text.text.text.text.text.text.text.text.text.text.text. TestObjSerializeandDeserialize <p> * <p> 설명 : 테스트 객체의 직렬화 및 사막화 <p> * @Author XUDP * @version 1.0 v * @CreateTime 2014-6-9 03:17:25 PM */public static void exceptrows void (args) serializeperson (); // 사람의 객체 직원 p = deserializeperson (); // deserial perons 객체 system.out.println (messageformat.format ( "name = {0}, age = {1}, sex = {2}", p.getname (), p.getage ()); } / ** * MethodName : SerializePerson * 설명 : 사람 객체 시리얼 화 * @Author XUDP * @throws filenotFoundException * @Throws IOException * / private static void serializeperson ()는 filenotfoundException, ioexception {personephent = new person (); person.setName ( "GaCl"); person.setage (25); person.setsex ( "male"); // ObjectOutputStream 객체 출력 스트림, 개인 개체를 person.txt 파일에 E 디스크에 저장하고 Person Object의 직렬화 작업을 완료하십시오. ObjectOutputStream oo = 새 대상 ObterOutputStream (새 파일 OutputStream (새 파일 ( "e : /person.txt")); oo.writeobject (사람); System.out.println ( "사람 객체 직렬화는 성공적으로!"); oo.close (); }/** * MethodName : DeserializePerson * 설명 : DeserializePerson Object * @Author XUDP * @return * @throws Exception * @throws ioException */private static person deserializePerson () 예외, ioException {객체 inputStream ois = new ObjectInputStream (new Pile ( ")); 개인 = (사람) ois.readobject (); System.out.println ( "사람 객체 사막화가 성공적으로!"); 귀환 담당자; }}코드 실행 결과는 다음과 같습니다.
사람을 성공적으로 시리얼링 한 후, ESK에서 Person.txt 파일이 생성되었으며, Dessorialization Person.txt of E Disk를 읽는 데 사용됩니다.
3. Serialversionuid의 역할
Seri al versi ui d : 문자 그대로 직렬화 된 버전 번호를 의미합니다. 직렬화 가능한 인터페이스를 구현하는 모든 클래스에는 직렬화 된 버전 식별자를 나타내는 정적 변수가 있습니다.
개인 정적 최종 최종 긴 SerialversionUid
SerialversionUid가 클래스에 추가되지 않으면 다음 경고가 나타납니다.
마우스를 클릭하면 아래 그림과 같이 SerialversionUid를 생성하는 대화 상자가 나타납니다.
SerialversionUid를 생성하는 두 가지 방법이 있습니다.
이러한 방식으로 생성 된 SerialversionUid는 예를 들어 1L입니다.
개인 정적 최종 최종 긴 SerialversionUID = 1L;
이러한 방식으로 생성 된 SerialversionUid는 클래스 이름, 인터페이스 이름, 메소드 및 속성 등을 기준으로 생성됩니다.
개인 정적 최종 최종 Long SerialversionUID = 460364234337807741L;
추가하면 다음과 같이 경고가 나타나지 않습니다.
그것에 대해 이야기 한 후, SerialversionUid (직렬화 된 버전 번호)의 사용은 무엇입니까? 다음 예제를 사용하여 SerialversionUid의 역할을 설명하고 다음 코드를 참조하십시오.
1 import java.io.file; 2 import java.io.fileInputStream; 3 import java.io.filenotfoundException; 4 import java.io.fileoutputStream; 5 가져 오기 java.io.ioexception; 6 import java.io.objectinputstream; 7 import java.io.objectoutputStream; 8 import java.io.serializable; 9 10 Public Class TestserialversionUid {11 12 Public STATIC AVOID MAIN (String [] Args)은 예외를 {13 SerializeCustomer (); // 고객 객체 14 고객 Customer = DeserializeCustomer (); // Deserial Customer Object 15 System.out.println (16} 17 18/** 19 * MethodName : SerializeCer 21 : * @Author XUDP22 * @throws filenotfoundException23 * @Throws IOException24 */25 개인 정적 무효 SerializeCustomer ()는 filenotfoundException, 26 IOException {27 Customer Customer = New Customer ( "GACL", 25); FileOutputStream (30 개의 새 파일 ( "e : /customer.txt")); xudp40 * @return41 * @throws Exception42 * @throws ioexception43 */44 개인 정적 고객 deserializecustomer ()는 예외, ioexception {45 ObjectInputStream OIS = new ObjectInputStream (새 FileInputStream ( "e :/customer.txt")); ois.readobject (); 48 System.out.println ( "고객 객체 사막화가 성공했습니다! "); 49 반환 고객; 50} 51} 52 53 /** 54 * <p> ClassName : Customer <P> 55 * <P> 설명 : 고객은 직렬화 가능한 인터페이스를 구현하고 직렬화 될 수 있으며 <P> 56 * @UDP57 * @version 1.0 V58 * @CreateTime 2014-6-9 04 : 1759 PM * /60 Classements inforination. {61 // serialversionuid62 개인 문자열 이름 없음; 63 개인 int 연령; 64 65 공개 고객 (문자열 이름, int age) {66 this.name = name; 67 this.age = age; 68} 69 70 / * 71 * @methodname toString72 * @desprioning (@desprioning) The The Object 73 * @auther xudpp7 string75 * @see java.lang.object#tostring () 76 */77 @override78 public string tostring () {79 return "name =" + name + ", age =" + age; 80} 81}실행 결과 :
직렬화와 사제화는 모두 성공적이었습니다.
다음과 같이 고객 클래스를 수정하고 추가 성 속성을 추가하겠습니다.
1 클래스 고객 구현 시리얼이즈 가능 {2 // SerialVersionUid 없음 고객 클래스 3 개인 문자열 이름에 정의되어 있지 않습니다. 4 개인 int 연령; 5 6 // 새로운 섹스 속성 7 개인 문자열 섹스; 8 9 공개 고객 (문자열 이름, int Age) {10 this.name = name; 11 this.age = Age; 12} 13 14 공개 고객 (문자열 이름, int 연령, 문자열 섹스) {15 this.name = name; 16 this.age = age; 17 this.sex = 섹스; xudp24 * @return string25 * @see java.lang.object#tostring () 26 */27 @atedreding28 public string toString () {29 return "name =" + name + ", age =" + age; 30} 31}그런 다음 desequence 작업을 수행하면 다음 예외 정보가 발생합니다.
1 스레드의 예외 "main"java.io.invalidclassexception : 고객; 2 로컬 클래스 호환성 : 3 스트림 클래스 디스크 SerialVersionUID = -8817559999432325, 4 로컬 클래스 SerialVersionUID = -5182532647273106745
이는 파일 스트림의 클래스와 클래스 경로의 클래스, 즉 수정 된 클래스의 클래스가 호환되지 않음을 의미합니다. 그들은 보안 메커니즘 고려 사항에 따라 있습니다. 프로그램은 오류를 던지고로드를 거부합니다. 그렇다면 직렬화 후 필드 나 방법을 추가해야한다면 어떨까요? 어떻게해야하나요? 즉, 직접 직접 지정하는 것입니다. TestSerialVersionUid 예제에서 고객 클래스의 SerialVersionUid가 지정되지 않은 경우 Java 컴파일러는 지문 알고리즘과 유사한이 클래스의 요약 알고리즘을 자동으로 수행합니다. 파일에 공간이 하나 더있는 한 결과 UID가 완전히 다르 므로이 숫자가 많은 클래스에서 고유한지 보장 할 수 있습니다. 따라서 필드를 추가 한 후 SerialversionUid가 지정되지 않기 때문에 컴파일러는 UID를 생성합니다. 물론 이전 파일에 저장된 것과 동일하지 않으므로 일관되지 않은 직렬화 버전 번호가있는 두 가지 오류가 있습니다. 따라서, 직렬 버전을 직접 지정하는 한, 우리는 이후 복원에 영향을 미치지 않고 직렬화 후 필드 나 방법을 추가 할 수 있습니다. 복원 된 객체를 여전히 사용할 수 있으며 사용할 방법이나 속성도 더 있습니다.
다음으로 고객 클래스를 계속 수정하고 SerialversionUid를 고객에게 지정하십시오. 수정 된 코드는 다음과 같습니다.
클래스 고객은 직렬화 가능 { / ** * SerialversionUid (SerialversionUid) 고객 클래스에 정의 된 SerialversionUid (Serialized Version Number) * / Private Static Final Long SerialversionUID = -5182532647273106745L; 개인 문자열 이름; 사적인 int 연령; // 새로운 섹스 속성 // 개인 문자열 섹스; 공개 고객 (문자열 이름, int age) {this.name = 이름; this.age = age; } /*공개 고객 (문자열 이름, int 연령, 문자열 섹스) {this.name = 이름; this.age = age; this.sex = 섹스; . }}직렬화 작업을 다시 실행하고 고객 객체를 Customer.txt 파일 스토리지로 직렬화 한 다음 고객 클래스를 수정하고 성 속성을 추가하십시오. 수정 된 고객 클래스 코드는 다음과 같습니다.
클래스 고객은 직렬화 가능 { / ** * SerialversionUid (SerialversionUid) 고객 클래스에 정의 된 SerialversionUid (Serialized Version Number) * / Private Static Final Long SerialversionUID = -5182532647273106745L; 개인 문자열 이름; 사적인 int 연령; // 새로운 섹스 속성 개인 문자열 섹스; 공개 고객 (문자열 이름, int age) {this.name = 이름; this.age = age; } 공개 고객 (문자열 이름, int 연령, 문자열 섹스) {this.name = 이름; this.age = age; this.sex = 섹스; } / * * @methodname tostring * @description 객체 클래스의 tostring () 메소드를 다시 작성하십시오 * @author xudp * @return string * @see java.lang.object#tostring () * / @override public String toString () {return "name =" + name + ", age =" + age; }}Desequence 작업을 수행하면 다음과 같이 이번에는 다음과 같이 Desequence가 성공할 것입니다.
4. SerialversionUid의 값
SerialversionUid의 값은 클래스의 내부 세부 사항을 기반으로 Java 런타임 환경에 의해 자동으로 생성됩니다. 클래스의 소스 코드가 수정되고 재 컴파일되면 새로 생성 된 클래스 파일의 SerialversionUid 값도 변경 될 수 있습니다.
클래스의 SerialversionUid의 기본값은 전적으로 Java 컴파일러의 구현에 따라 다릅니다. 동일한 클래스의 경우, 다른 Java 컴파일러로 컴파일하면 다른 직렬 버전으로 이어질 수 있으며 동일 할 수도 있습니다. SerialversionUid의 독립성과 확실성을 향상시키기 위해 직렬화 가능한 클래스에 표시된 SerialversionUid를 정의하여 명확한 값을 할당하는 것이 좋습니다.
SerialVersionUid를 명시 적으로 정의하기위한 두 가지 목적이 있습니다.
1. 경우에 따라, 다른 버전의 클래스가 직렬화와 호환 될 것으로 예상되므로, 다른 버전의 클래스가 동일한 직렬 버전을 갖도록해야합니다.
2. 경우에 따라, 다른 버전의 클래스는 직렬화와 호환 될 것으로 예상되지 않으므로 다른 버전의 클래스마다 서로 다른 시리얼 버전을 갖도록해야합니다.
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!