Java对象序列化是一种将Java对象转换为字节序列的过程,它可以将Java对象的状态保存到存储媒体中,以便在以后重新构造出完全相同的对象。它可以用于在网络上传送对象,也可以用于保存和恢复数据。
Java对象序列化有很多作用:
1. 它可以将Java对象的状态保存到存储媒体中,以便在以后重新构造出完全相同的对象。 2. 它可以用于在网络上传送对象,也可以用于保存和恢复数据。 3. 它可以用来实现远程方法调用(RMI)。 4. 它可以使得我们能够在不同的平台之间传递对象。 5. 它还可以使得我们能够将一个Java应用中的内存数据快速而方便地保存到文件中,然后再读出来。
ObjectOutputStream类的一个对象用于序列化一个对象。
ObjectInputStream类的一个对象用于反序列化一个对象。
ObjectOutputStream继承自OutputStream。 ObjectInputStream继承自InputStream。
类必须实现Serializable或Externalizable接口以便序列化或反序列化。
Serializable接口是一个标记接口。
如果我们想要一个Person类的对象被序列化,我们需要声明Person类如下:
public class Person implements Serializable { }
Java负责处理从/向流读取/写入Serializable对象的细节。我们只需要将对象写入/读取流到流类中的一个方法。
实现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类。
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(); } } }
上面的代码生成以下结果。
以下代码显示如何创建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(); } } }
上面的代码生成以下结果。
Java IO教程 -Java异步I/O在同步文件I/O中,对I/O操作的请求将等待,直到I/O操作完成。在异步文件I/O中,I/O操作的请求由系统异...
Java IO教程 -Java文件内容文件的内容类型Files.probeContentType(Path path)方法探测文件的内容类型。该方法以多用途Internet邮...
Java数据类型教程 -Java可变长度数组Java数组不能增长。为了创建一个可扩展的数组,我们可以使用ArrayList或Vector。ArrayList和...
Java数据类型教程 -Java基本数据类型Java定义了八种基本类型的数据:byte,short,int,long,char,float,double和boolean。基...
Java数据类型教程 -Java long数据类型long数据类型是64位有符号Java原始数据类型。当对整数的计算结果可能超出int数据类型的范围...