本文共 4124 字,大约阅读时间需要 13 分钟。
Java对象序列化是Java编程中实现对象持久化和传输的重要机制,通过默认序列化机制或自定义方法,可以控制对象序列化的行为。本文将详细介绍Java对象序列化的基础知识及其常见应用场景。
Java平台允许我们在内存中创建可复用的Java对象。然而,这些对象通常只能在JVM运行期间存在。一旦JVM停止运行,这些对象的状态将不会被保存。为了实现对象的持久化(如文件存储或网络传输),Java提供了对象序列化机制。
以下是一个简单的Java类,用于演示对象序列化的过程。
package testSeri;import java.io.Serializable;public class Person implements Serializable { private String name; private Integer age; private Gender gender; public Person() { System.out.println("non-arg constructor"); } public Person(String name, Integer age, Gender gender) { System.out.println("arg constructor"); this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public Integer getAge() { return age; } public Gender getGender() { return gender; } public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setGender(Gender gender) { this.gender = gender; } public String toString() { return "[" + name + ", age=" + age + ", gender=" + gender + "]"; }}
package testSeri;import java.io.*;public class SerializibleTest { public static void main(String args[]) throws Exception { File file = new File("person.out"); ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file)); Person person = new Person("fuck", 10, Gender.MALE); oout.writeObject(person); oout.close(); ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file)); Object newPerson = oin.readObject(); oin.close(); System.out.println(newPerson); }}
默认情况下,Java的序列化机制会序列化对象的成员变量,并依赖于类的定义。如果一个类包含复杂的对象(如容器类),默认序列化会引起递归调用,造成性能上的影响。为了应对这些问题,Java提供了多种自定义序列化方法。
Transient标记的字段不会被序列化。例如:
private transient Integer age;
可以通过自定义方法来控制序列化行为:
private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(age);}private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); age = in.readInt();}
Externalizable提供了更大的控制权,但依然继承自Serializable:
public class Person implements Externalizable { private String name; private transient Integer age; private Gender gender; public Person() { ... } public Person(String name, Integer age, Gender gender) { ... } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(age); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); age = in.readInt(); } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeObject(age); out.writeObject(gender); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); age = (Integer) in.readObject(); gender = (Gender) in.readObject(); }}
在序列化中,readResolve()方法可以将反序列化后的对象与原对象重新关联。例如,在Singleton模式中:
public class Person implements Serializable { private static final Person instance = new Person("John", 31, Gender.MALE); private String name; private Integer age; private Gender gender; private Person() { System.out.println("non-arg constructor"); } private Person(String name, Integer age, Gender gender) { System.out.println("arg constructor"); this.name = name; this.age = age; this.gender = gender; } private void readResolve() throws ObjectStreamException { this.name = "{" + super.readResolve().getName() + "}"; age = super.readResolve().age; gender = super.readResolve().gender; return instance; }}
通过以上方法,可以对Java对象序列化进行更细致的控制,实现更加灵活的持久化和传输需求。
转载地址:http://fbryk.baihongyu.com/