Java對象序列化
ObjectOutputStream
類的對象用於序列化對象。ObjectInputStream
類的對象用於反序列化一個對象。ObjectOutputStream
繼承自OutputStream
。ObjectInputStream
繼承自InputStream
。
類必須實現Serializable
或Externalizable
接口以便序列化或反序列化。Serializable
接口是一個標記接口。如果想要一個Person
類的對象被序列化,需要聲明Person
類如下:
public class Person implements Serializable {
}
Java負責處理從/向流讀取/寫入Serializable
對象的細節。只需要將對象傳到流流類的write/read
方法之一。實現Externalizable
接口能夠更好地控制從流中讀取對象和向對象寫入對象。
它繼承Serializable
接口,聲明如下:
public interface Externalizable extends Serializable {
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
void writeExternal(ObjectOutput out) throws IOException;
}
當從流中讀取一個對象時,Java調用readExternal()
方法。當向一個流寫一個對象時,它調用writeExternal()
方法。
必須編寫邏輯來分別讀取和寫入readExternal()
和writeExternal()
方法中的對象的字段。
實現Externalizable
接口的類如下所示:
public class Person implements Externalizable {
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// Write the logic to read the Person object fields from the stream
}
public void writeExternal(ObjectOutput out) throws IOException {
// Write the logic to write Person object fields to the stream
}
}
序列化對象
以下代碼創建ObjectOutputStream
類的對象,並將對象保存到person.ser
文件。
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"));
要將對象保存到ByteArrayOutputStream
,構造一個對象輸出流如下:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Creates an object output stream to write objects to the byte array output stream
ObjectOutputStream oos = new ObjectOutputStream(baos);
使用ObjectOutputStream
類的writeObject()
方法通過將對象引用作爲參數傳遞來序列化對象,如下所示:
oos.writeObject(p1);
最後,當完成將所有對象寫入時,使用close()
方法關閉對象輸出流:
oos.close();
以下代碼顯示Person
類如何序列化,它實現可序列化接口(Serializable
)。
import java.io.Serializable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
class Person implements Serializable {
private String name = "Unknown";
private String gender = "Unknown";
private double height = Double.NaN;
public Person(String name, String gender, double height) {
this.name = name;
this.gender = gender;
this.height = height;
}
@Override
public String toString() {
return "Name: " + this.name + ", Gender: " + this.gender + ", Height: "
+ this.height;
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("John", "Male", 1.7);
Person p2 = new Person("Wally", "Male", 1.7);
Person p3 = new Person("Katrina", "Female", 1.4);
File fileObject = new File("person.ser");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
fileObject))) {
oos.writeObject(p1);
oos.writeObject(p2);
oos.writeObject(p3);
// Display the serialized objects on the standard output
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面的代碼生成以下結果。
Name: John, Gender: Male, Height: 1.7
Name: Wally, Gender: Male, Height: 1.7
Name: Katrina, Gender: Female, Height: 1.4
反序列化對象
以下代碼顯示如何創建ObjectInputStream
類的對象,並從person.ser
文件讀取對象。
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"));
要從ByteArrayInputStream
讀取對象,請按如下所示創建對象輸出流:
ObjectInputStream ois = new ObjectInputStream(Byte-Array-Input-Stream-Reference);
使用ObjectInputStream
類的readObject()
方法來反序列化對象。
Object obj = oos.readObject();
最後,關閉對象輸入流如下:
ois.close();
以下代碼顯示如何從文件讀取對象。
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Main {
public static void main(String[] args) {
File fileObject = new File("person.ser");
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
fileObject))) {
Person p1 = (Person) ois.readObject();
Person p2 = (Person) ois.readObject();
Person p3 = (Person) ois.readObject();
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
外部化對象序列化
要序列化和反序列化可外部化對象,請實現Externalizable
接口。
import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
class PersonExt implements Externalizable {
private String name = "Unknown";
private String gender = "Unknown";
private double height = Double.NaN;
public PersonExt() {
}
public PersonExt(String name, String gender, double height) {
this.name = name;
this.gender = gender;
this.height = height;
}
public String toString() {
return "Name: " + this.name + ", Gender: " + this.gender + ", Height: " + this.height;
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.name = in.readUTF();
this.gender = in.readUTF();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(this.name);
out.writeUTF(this.gender);
}
}
public class Main {
public static void main(String[] args) {
PersonExt p1 = new PersonExt("John", "Male", 6.7);
PersonExt p2 = new PersonExt("Wally", "Male", 5.7);
PersonExt p3 = new PersonExt("Katrina", "Female", 5.4);
File fileObject = new File("personext.ser");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileObject))) {
oos.writeObject(p1);
oos.writeObject(p2);
oos.writeObject(p3);
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
} catch (IOException e1) {
e1.printStackTrace();
}
fileObject = new File("personext.ser");
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileObject))) {
p1 = (PersonExt) ois.readObject();
p2 = (PersonExt) ois.readObject();
p3 = (PersonExt) ois.readObject();
// Let's display the objects that are read
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
// Print the input path
System.out.println("Objects were read from " + fileObject.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的代碼生成以下結果。
Name: John, Gender: Male, Height: 6.7
Name: Wally, Gender: Male, Height: 5.7
Name: Katrina, Gender: Female, Height: 5.4
Name: John, Gender: Male, Height: NaN
Name: Wally, Gender: Male, Height: NaN
Name: Katrina, Gender: Female, Height: NaN
Objects were read from F:\website\yiibai\worksp\personext.ser