java中属性外部化_用Java可外部化
java中屬性外部化
在理解Externalizable接口之前,您需要了解序列化。您可以在java中的序列化上閱讀有關序列化的更多信息。
Java提供了一種稱為序列化的機制,以按字節的有序或字節序列的形式持久化Java對象,其中包括對象的數據以及有關對象的類型和存儲在對象中的數據類型的信息。
可外部化:
顧名思義,這是對序列化進行外部化。如果要自定義序列化機制,則可以使用它。它使用自定義的書面機制來執行對象的編組和解組.Externalizable接口擴展了Serializable接口。 如果實現此接口,則需要重寫以下方法。
@Overridepublic void readExternal(ObjectInput arg0) throws IOException,ClassNotFoundException {}@Overridepublic void writeExternal(ObjectOutput arg0) throws IOException {}現在讓我們看看序列化是如何發生的:
在發送方:
JVM檢查類是否實現了可外部化。如果是,則使用writeExternal()方法對對象進行序列化。如果不實現可外部化但實現serializable,則使用ObjectOutputStream對對象進行序列化。
在接收方:
重建對象并使其可外部化時,不使用args構造函數創建實例,并調用readExternal。如果該對象不可外部化但可序列化,則使用ObjectInputStream重建對象。
讓我們從與Java序列化中使用的示例相同的示例開始。
在src-> org.arpit.javapostsforlearning中創建Employee.java
Employee.java:
package org.arpit.javapostsforlearning; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput;public class Employee implements Externalizable{ int employeeId;String employeeName;String department;String nationality;public Employee(){}public int getEmployeeId() {return employeeId;}public void setEmployeeId(int employeeId) {this.employeeId = employeeId;}public String getEmployeeName() {return employeeName;}public void setEmployeeName(String employeeName) {this.employeeName = employeeName;}public String getDepartment() {return department;}public void setDepartment(String department) {this.department = department;}public String getNationality() {return nationality;}public void setNationality(String nationality) {this.nationality = nationality;}@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {employeeId=in.readInt();employeeName=(String) in.readObject();}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeInt(employeeId);out.writeObject(employeeName);} }如果要實現可外部化,則必須沒有args構造函數。
在org.arpit.javapostsforlearning中創建ExternalizableMain.java
ExternalizableMain.java:
package org.arpit.javapostsforlearning; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;public class ExternalizableMain {/*** @author Arpit Mandliya*/public static void main(String[] args) {Employee emp = new Employee();emp.setEmployeeId(101);emp.setEmployeeName("Arpit");emp.setDepartment("CS");//Serializetry{FileOutputStream fileOut = new FileOutputStream("employee.ser");ObjectOutputStream outStream = new ObjectOutputStream(fileOut);outStream.writeObject(emp);outStream.close();fileOut.close();}catch(IOException i){i.printStackTrace();}//Deserializeemp = null;try{FileInputStream fileIn =new FileInputStream("employee.ser");ObjectInputStream in = new ObjectInputStream(fileIn);emp = (Employee) in.readObject();in.close();fileIn.close();}catch(IOException i){i.printStackTrace();return;}catch(ClassNotFoundException c){System.out.println("Employee class not found");c.printStackTrace();return;}System.out.println("Deserialized Employee...");System.out.println("Emp id: " + emp.getEmployeeId());System.out.println("Name: " + emp.getEmployeeName());} }運行它:當運行ExternalizableMain.java時,您將獲得以下輸出
Deserialized Employee... Emp id: 101 Name: Arpit如果您已經具有可序列化的功能,那么為什么需要完全可外部化!:
- 當您使用serializable可序列化任何對象時,除字段外,所有屬于對象映射且可以使用實例變量訪問的對象也將被序列化。例如:
- 如果您擁有Employee類,并且其超類是person,則它將序列化所有超類對象(例如person),直到達到“ Object”類為止。
- 同樣,如果Employee具有地址類的實例變量,則它將也序列化整個地址對象圖。
當您要序列化的是employeeId和employeeName時,您真的要這么多開銷嗎?
- 當您使用序列化速度很慢時,JVM使用反射。
- 進行序列化時,有關類描述的信息(包括其超類的描述和與該類關聯的實例變量)也會存儲在流中。同樣,這也是性能問題
繼承中的繼承:
現在我們將了解繼承如何影響外部化,因此可能會有很多情況說明超類是否可外部化,如果不是,那么您將如何處理它以及它是如何工作的,讓我們舉個例子來看。
我們將創建Person.java,它將是Employee的超類。
情況1:如果超類未實現Externalizable:
如果超類未實現externalizable,則需要在實現Externalizable的子類中序列化superclass的字段。
人.java
package org.arpit.javapostsforlearning; public class Person {String name="default";String nationality;public Person(){System.out.println("Person:Constructor");}public Person(String name, String nationality) {super();this.name = name;this.nationality = nationality;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNationality() {return nationality;}public void setNationality(String nationality) {this.nationality = nationality;}}在org.arpit.javapostsforlearning中創建Employee.java
Employee.java:
package org.arpit.javapostsforlearning; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; ;public class Employee extends Person implements Externalizable{ int employeeId;String department;public Employee(){}public Employee(int employeeId,String name,String department,String nationality){super(name,nationality);this.employeeId=employeeId;this.department=department;System.out.println("Employee:Constructor");}public int getEmployeeId() {return employeeId;}public void setEmployeeId(int employeeId) {this.employeeId = employeeId;}public String getDepartment() {return department;}public void setDepartment(String department) {this.department = department;}@Override public void writeExternal(ObjectOutput out) throws IOException {/*since superclass does not implement externalizable, you need to serialize super class field in this class itself*///superclass fieldsout.writeObject(name);out.writeObject(nationality);// its own fieldsout.writeInt(employeeId);out.writeObject(department); }@Override public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {/*since superclass does not implement externalizable, you need to deserialize super class field in this class itself*///superclass fieldsname=(String) in.readObject();nationality=(String) in.readObject();// its own fieldsemployeeId=in.readInt();department=(String) in.readObject();} }在org.arpit.javapostsforlearning中創建ExternalizableMain.java
ExternalizableMain.java:
package org.arpit.javapostsforlearning; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;public class ExternalizableMain {/*** @author Arpit Mandliya*/public static void main(String[] args) {//SerializeEmployee emp = new Employee(101,"Arpit","CS","Indian");System.out.println("Before serializing");System.out.println("Emp id: " + emp.getEmployeeId());System.out.println("Name: " + emp.getName());System.out.println("Department: " + emp.getDepartment());System.out.println("Nationality: " + emp.getNationality());System.out.println("************");System.out.println("Serializing");try{FileOutputStream fileOut = new FileOutputStream("employee.ser");ObjectOutputStream outStream = new ObjectOutputStream(fileOut);outStream.writeObject(emp);outStream.close();fileOut.close();}catch(IOException i){i.printStackTrace();}//DeserializeSystem.out.println("************");System.out.println("Deserializing");emp = null;try{FileInputStream fileIn =new FileInputStream("employee.ser");ObjectInputStream in = new ObjectInputStream(fileIn);emp = (Employee) in.readObject();in.close();fileIn.close();}catch(IOException i){i.printStackTrace();return;}catch(ClassNotFoundException c){System.out.println("Employee class not found");c.printStackTrace();return;}System.out.println("After serializing");System.out.println("Emp id: " + emp.getEmployeeId());System.out.println("Name: " + emp.getName());System.out.println("Department: " + emp.getDepartment());System.out.println("Nationality: " + emp.getNationality());} }運行 :
當運行ExternalizableMain.java時,您將獲得以下輸出:
Employee:Constructor Before serializing Emp id: 101 Name: Arpit Department: CS Nationality: Indian ************ Serializing ************ Deserializing Person:Constructor After serializing Emp id: 101 Name: Arpit Department: CS Nationality: Indian情況2:如果超類實現了Externalizable:
如果超類實現了externalizable,那么它還將具有readExternal()和writeExternal()方法,因此它將在這些方法中序列化其自己的字段。
人.java
package org.arpit.javapostsforlearning;import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput;public class Person implements Externalizable{String name="default";String nationality;public Person(){System.out.println("Person:Constructor");}public Person(String name, String nationality) {super();this.name = name;this.nationality = nationality;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNationality() {return nationality;}public void setNationality(String nationality) {this.nationality = nationality;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(name);out.writeObject(nationality);}@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {name=(String) in.readObject();nationality=(String) in.readObject();}}在org.arpit.javapostsforlearning中創建Employee.java
Employee.java:
package org.arpit.javapostsforlearning; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; ;public class Employee extends Person implements Externalizable{ int employeeId;String department;public Employee(){}public Employee(int employeeId,String name,String department,String nationality){super(name,nationality);this.employeeId=employeeId;this.department=department;System.out.println("Employee:Constructor");}public int getEmployeeId() {return employeeId;}public void setEmployeeId(int employeeId) {this.employeeId = employeeId;}public String getDepartment() {return department;}public void setDepartment(String department) {this.department = department;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {super.writeExternal(out);out.writeInt(employeeId);out.writeObject(department);}@Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {super.readExternal(in);employeeId=in.readInt();department=(String) in.readObject();} }在org.arpit.javapostsforlearning中創建ExternalizableMain.java
ExternalizableMain.java:
package org.arpit.javapostsforlearning; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;public class ExternalizableMain {/*** @author Arpit Mandliya*/public static void main(String[] args) {//SerializeEmployee emp = new Employee(101,"Arpit","CS","Indian");System.out.println("Before serializing");System.out.println("Emp id: " + emp.getEmployeeId());System.out.println("Name: " + emp.getName());System.out.println("Department: " + emp.getDepartment());System.out.println("Nationality: " + emp.getNationality());System.out.println("************");System.out.println("Serializing");try{FileOutputStream fileOut = new FileOutputStream("employee.ser");ObjectOutputStream outStream = new ObjectOutputStream(fileOut);outStream.writeObject(emp);outStream.close();fileOut.close();}catch(IOException i){i.printStackTrace();}//DeserializeSystem.out.println("************");System.out.println("Deserializing");emp = null;try{FileInputStream fileIn =new FileInputStream("employee.ser");ObjectInputStream in = new ObjectInputStream(fileIn);emp = (Employee) in.readObject();in.close();fileIn.close();}catch(IOException i){i.printStackTrace();return;}catch(ClassNotFoundException c){System.out.println("Employee class not found");c.printStackTrace();return;}System.out.println("After serializing");System.out.println("Emp id: " + emp.getEmployeeId());System.out.println("Name: " + emp.getName());System.out.println("Department: " + emp.getDepartment());System.out.println("Nationality: " + emp.getNationality());} }運行 :
當運行ExternalizableMain.java時,您將獲得以下輸出:
Employee:Constructor Before serializing Emp id: 101 Name: Arpit Department: CS Nationality: Indian ************ Serializing ************ Deserializing Person:Constructor After serializing Emp id: 101 Name: Arpit Department: CS Nationality: Indian在此示例中,由于Person類在其自己的writeExternal和readExternal方法中存儲和還原其字段,因此您無需在子類中保存/恢復超類字段,但是如果您仔細觀察Employee類的writeExternal和readExternal方法,您將發現您仍然需要首先調用super.xxxx()方法,該方法確認可外部化對象還必須與其父類型協調才能保存和恢復其狀態的語句。
可外部化的缺點:
- 如果對類定義進行了任何更改,則需要相應地維護writeExternal()和readExternal。
- 正如我們在示例中看到的,子類對象必須與其父類協調才能保存和存儲其狀態(通過從子類中調用super.xxxx()方法)
翻譯自: https://www.javacodegeeks.com/2014/03/externalizable-in-java.html
java中屬性外部化
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java中属性外部化_用Java可外部化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为荣耀3x如何连接电脑(华为ax3路由
- 下一篇: oppo怎么设置分屏(oppo手机怎么分