Java는 Serialization이라는 메커니즘을 제공합니다. Java 객체는 객체의 데이터뿐만 아니라 객체의 유형 및 객체에 저장된 데이터 유형을 포함하는 순서대로 형식 또는 바이트 시퀀스를 통해 지속됩니다.
따라서 객체를 직렬화 한 경우 객체 유형 및 기타 정보를 통해 읽고 비활성화 할 수 있으며 마지막으로 물체의 프로토 타입을 얻을 수 있습니다.
ObjectInputStream 및 ObjectOututputStream 객체는 직렬화 및 후면 순차 방법을 포함한 높은 레벨 스트리밍 객체입니다.
ObjectOutputStream에는 직렬화 된 객체에 대한 많은 방법이 있습니다.
private void writeObject (ObjectOutputStream os)는 ioexception {} 던지기
유사한 ObjectInputStream은 다음 방법을 제공합니다.
Private Void Brand (ObjectInputStream IS)는 IoException, ClassNotFoundException {} 던지기
그렇다면 어디에서 직렬화해야합니까? 직렬화는 일반적으로 네트워크 전송 데이터를 사용하거나 객체를 파일에 저장합니다. 여기에 언급 된 데이터는 텍스트가 아니라 객체입니다.
문제는 이제 네트워크 아키텍처와 하드 디스크가 이진과 바이트 만 식별 할 수 있으며 Java 객체를 인식 할 수 없다는 것입니다.
직렬화는 Java 객체의 값/상태를 바이트로 변환하여 네트워크를 통해 전송하거나 저장하는 것입니다. 또한 종속성 직렬화는 바이트 코드를 읽고 Java 객체로 다시 변환하는 것입니다.
SerialVersionUid 개념
SerialversionUid는 사막화 과정에서 동일한 객체 (직렬화에 사용할 수 있음)를로드 할 수 있도록하는 데 사용됩니다. SerialversionUid는 객체에 대한 버전 컨트롤입니다. 더 많은 정보를 얻으려면 Java 직렬화의 SerialversionUid를 참조 할 수 있습니다.
직렬화를 위해 :
단계는 다음과 같습니다.
목록을 보자 :
src-> org.arpit.javapostsforning에서 Employee.java를 만듭니다
1. Employee.java
org.arpit.javapostsforning; = EmployeeId;} public string getemployeename () {return Employeename;} public void setemployeename (String Employeename) {this.employeena me = Employeename;} public string getDepPartment () {return department;} public void setDepment (String Department) {this. DepApartment = Department;}}
보시다시피, 클래스 직렬화가 필요한 경우이 인터페이스는 마커 인터페이스입니다.
Java의 마커 인터페이스는 필드 나 방법이없는 인터페이스입니다. 빈 인터페이스를 Java의 마커 인터페이스라고합니다.
2.serializemain.java
org.arpit.java.io.fileoutputstream; ] ARGS) {Emplyee Emp. ser "); ObjectPutStream Outstream = New ObjectPutStream (FileOut); outstream.writeObject (EMP); outstream.close (); 예외 i) {I.printstacktrace ();}}}
역 -순위화 :
단계는
패키지 src-> org.arpit.javapostsforLearning에서 deserializemain.java를 작성하십시오
3.deserializemain.java
org.arpit.javapostsforning; null; try {new eleverinputStream (fileinputStream); ioexception i) {i.printstacktrace (); ... "); system.out.println ("emp id : " + emp.getemployeeid ()); system.out.println ("이름 : " + emp.getemployeename ()); stem.out.println (") 부서 : " + emp.getDepPartment ());}}
4. 실행 :
먼저 serializemain.java를 실행 한 다음 deserializemain.java를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
Desserialized emblayee ... emp id : 101name : arpitdepapartment : cs
이런 식으로, 우리는 직원 대상을 연속화하여이를 수행했습니다. 이것은 단순 해 보이지만 객체 참조와 상속이 포함되어 있으면 상황이 복잡해집니다. 다양한 경우에 직렬화를 달성하는 방법을보기 위해 예제를 하나씩 살펴 보겠습니다.
CASE 1- 개체가 다른 개체를 인용하는 경우 어떻게해야합니까?
우리는 이미 가장 간단한 시퀀스 기반 예제를 보았습니다. 우리는 어떻게 직렬화 할 수 있습니까? 인용 된 물체도 직렬화됩니까? 예, 명시 적으로 직렬화 될 필요는 없습니다. 객체가 직렬화되면 기준 객체가 포함 된 경우 Java Serialization은 객체의 전체 객체 다이어그램을 자동으로 직렬화합니다. 예를 들어, 직원은 이제 주소 객체를 인용하고 주소는 다른 객체 (예 : 홈)를 인용 한 다음 직원 객체를 직렬화하면 주소 및 홈과 같은 모든 인용 객체가 직렬화에 의해 자동으로 직렬화됩니다 주소 클래스를 만들고 주소의 객체를 참조로 추가하여 직원 클래스에 추가하겠습니다.
직원. 자바 :
org.arpit.javapostsforning; this.employeeid = EmployeeId;} public string getemployeename () {return EmployeeEename;} public void setempoloyeename (string eployeename) {this.emplayeename = Employeeeename;} public string getDepPartment () {return department;} public void setdeppartment (문자열 부서) { this.department = department;} 공개 주소 getAddress () {return address;} public void setAddress (주소 주소) {this.address = address};
org.arpit.javapostsforlerning 패키지에서 주소를 작성하십시오
address.java :
org.arpit. 이 .city = city;} public int gethomeno () {return homeno;} public void sethomeno (int home) {this.homeno = homeno;} public stringststreet () {street;} public void setstreet (String Street) {this. street = street;} public String getCity () {return city;} public void setcity (String City) {this.city = city;}}
org.arpit.javapostsforlerning에서 Serializedeserializemain.java를 만듭니다
Serializedeserializemain.java :
org.arpit.java.io.fileoutstream; Mandliya */ public static void main (string [] args) {emplyee (101); 88, "Mg Road", "Pune"); SETADDRESS (주소); close (ioxception i) {i.printstacktrace () /deserialize emper {fileInputStream " in.reamoBject (); Deserialized Employee ... "); System .out.println ("emp id : " + emp.getemployeeid ()); System.out.println ("이름 : " + emp.getemployeename ()); mp.getDepartment () 주소 = emp.getAddress (); "City :"+address.getCity ());
실행 :
Serializedeserializemain.java를 실행할 때. 그러한 결과를 얻을 수 있습니다.
java.io.notserializableException : org.arpit.javapostsforning.address at java.io.writeobject0 (알 수없는 소스) java.i o.objectstream.defaultwritefields (unseldectresm.writeSerialdata) at Java.io.objectputStream.writeordinaryObject (알 수없는 소스) at java.io.objecttream.writeobject0 (unknown source) at java.io.ob.ob jectoutputstream.writeobject (알 수없는 소스)
우리는 그것이 어디에서 잘못되었는지 설명 할 것입니다. 주소 클래스도 직렬화 할 수 있어야한다고 말하는 것을 잊었습니다. 그런 다음 주소 클래스는 Serialzable 인터페이스를 상속해야합니다.
address.java :
java.io .city = city;} public int gethomeno () {return homeno;} public void sethomeno (int homeno) {this.homeno = homeno;} public stringstreet () {) retrice setstreet (String Street) {this this this .street = street;} public String getCity () {return city;} public void setCity (String City) {this.city = city;}}}
다시 실행 :
다시 실행할 때 Serializedeserializemain.java. 다음 결과를 얻을 수 있습니다
Desserialized emblayee ... emp id : 101name : arpitdepartment : cscity : 푸네
사례 2 : 참조 객체의 소스 코드에 액세스 할 수없는 경우 (예 : 위의 주소 클래스의 소스 코드에 액세스 할 수 없습니다).
주소 클래스에 액세스 할 수없는 경우 주소 클래스에서 직렬화 가능한 인터페이스를 어떻게 구현할 수 있습니까? 그것을 달성하는 또 다른 방법이 있습니까? 예, 다른 클래스를 만들고 주소를 물려받은 다음 직렬화 가능한 인터페이스를 상속받을 수 있지만 다음 상황에서는이 솔루션이 실패합니다.
참조 클래스가 최종으로 정의 된 경우
참조 클래스가 다른 비 -서식화 된 객체를 참조하는 경우
그렇다면 직원 개체를 어떻게 직렬화 할 수 있습니까? 해결책은 전환을 표시하는 것입니다. 필드를 직렬화 할 필요가 없으면 과도로 표시하십시오.
과도 주소 주소
직원 클래스에서 주소가 과도로 표시된 후 프로그램을 실행하십시오. 주소 참조가 심해 과정에서 무효가되므로 NullPointerException을 얻게됩니다.
사례 3- 참조 객체의 상태를 저장해야한다면 어떻게해야합니까? (예 : 주소 개체)
Deepertine 과정에서 주소를 과도로 표시하면 NULL 결과가 반환됩니다. 그러나 여전히 상태를 저장 해야하는 경우 주소 객체를 직렬화해야합니다. Java Serialization은 특정 시그니처 개인 방법을 제공하는 경우 직렬화/Deepertine 중에 호출됩니다.
직원. 자바 :
org.arpits 공개 int getemployeeid () {return EmployeeId; ;} public string getDepApartment () {return department;} public void setDepartment (문자열 부서)} 공개 주소 getAddress () {반환 주소;} public void setAddress (주소 주소) {this.address = address;} private void writeObject (ObjectOutputStream OS)는 ioException, classNotFoundException {os.defaultWriteObject (); ;}} private void readObject (ObjectInputStream is)는 introws foundExcept {is.defaultreadObject (); .readObject (); 주소 (Homeno, Street, City);} {e.printstacktrace ()};
명심해야 할 또 다른 사항, ObjectInputStream은 Data Writing 데이터의 순서가 일관되게 읽습니다.
주소를 만듭니다
address.java :
org.arpit.java = street; this.ci = city;} public int gethomeno () {return homeno;} public void sethomeno (int homeno) {this.homeno = public string getStreet () {return setstreet (String Street) { this.street = street;} public String getCity () {return city;} public void setCity (String City) {this.city = city};
Serializedeserializemain.java를 작성하십시오
Serializedeserializemain.java :
org.arpit.java.io.fileoutstream; Mandliya */ public static void main (string [] args) {emplyee (101); 88, "Mg Road", "Pune"); SETADDRESS (주소); close (ioxception i) {i.printstacktrace () /deserialize emper {fileInputStream " in.reamoBject (); Deserialized Employee ... "); System .out.println ("emp id : " + emp.getemployeeid ()); System.out.println ("이름 : " + emp.getemployeename ()); mp.getDepartment () 주소 = emp.getAddress (); "City :"+address.getCity ());
달리다:
Serializedeserializemain.java를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
Desserialized emblayee ... emp id : 101name : arpitdepartment : cscity : 푸네
이제 직렬화되기 전과 마찬가지로 주소 객체의 상태를 얻습니다.
직렬화 상속 :
이제 상속이 직렬화에 어떤 영향을 미치는지 살펴 보겠습니다. 부모 클래스가 직렬화되었는지 여부에 관계없이 많은 예제로 이어질 것입니다. 부모 클래스가 직렬화되지 않은 경우, 우리는 무엇을하고 어떻게 작동하는지. 예를 살펴 보겠습니다.
우리는 직원의 부모 클래스로서 person.java를 만들 것입니다.
사례 4 : 부모 클래스가 직렬화 된 경우
상위 클래스가 직렬화 할 수있는 경우 모든 상속 클래스가 직렬화됩니다.
사례 5 : 부모 클래스가 직렬화되지 않으면 어떻게해야합니까?
상위 클래스가 비소화되지 않은 경우 처리 방법은 매우 다릅니다.
상위 클래스가 비소화되지 않은 경우 매개 변수 생성자 함수가 없어야합니다.
사람. 자바
org.arpit.javapostsforning {string name = "systal.out.println ("person : constructor "); super (); this.name = name; ;} 공공 공허 setNationality (문자열 국적) {this.nationality = 국적;}}
Employee.java를 만듭니다
직원. 자바 :
org.arpit.javapostsforning; .employeeid = heployeeid; department.out.println; Department;} public void setDepPartment (문자열 부서) {this.deppartment = Department;}}
Serializedeserializemain.java를 작성하십시오
Serializedeserializemain.java :
org.arpit.java.io.fileoutstream; mandliya */public static void main (String [] args) {// 새로운 직원 (101, "Arpit", "Indian"); .println ( "emp." getDepPartment ()) Outstream.writeObject (EMP); Catch (IoException i) {I.PrintStackTrace ();} // system.out.println *********** ";);) ;; try {fileInputStream fileIn = new FileInputStream ("Employeee.ser ");) in.readObject (); in.close (); filein.close () } catch (ioxception i) {I.PrintStackTrace (); (Synializate.out.println; "부서 :" + emp.getDepPartment ());
달리다:
Serializedeserializemain.java를 실행하면 부모 클래스가 직렬화되지 않으면 부모 클래스에 상속 된 모든 인스턴스 변수 값이 초기화됩니다. 여기에서 이름은 직접 상속되므로 심해 과정에서 이름이 기본값으로 초기화됩니다.
사례 6- 부모 클래스가 직렬화 된 경우, 직렬화 된 것으로 클래스를 상속받을 필요는 없습니다.
클래스를 상속하기 위해 클래스를 상속받지 않으려면 WriteObject () 및 readObject () 메소드를 구현해야하며 NotserializableException의 이상을 버려야합니다.
사례 7- 정적 변수가 직렬화 될 수 있습니까?
할 수 없습니다. 정적 변수는 객체를 직렬화 할 때 클래스 레벨이므로 정적 변수를 직렬화 할 수 없습니다.
요약 :