序列化的控制主要有三种方式:
- 实现Externalizable接口;
- 实现Serializable接口 + transient修饰符;
- 实现Externalizable接口的替代方案:实现Serializable + 添加方法;
1、实现Externalizable接口:
对于一个Externalizable对象而言,在序列化和反序列化中需要调用默认的构造函数,所以需要注意默认构造函数的访问控制符是否得当!
import java.io.Externalizable; 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; public class Blip3 implements Externalizable { private int i; private String s; // No initialization public Blip3() { System.out.println("Blip3 Constructor"); // s, i not initialized } public Blip3(String x, int a) { System.out.println("Blip3(String x, int a)"); s = x; i = a; // s & i initialized only in non-default constructor. } public String toString() { return s + i; } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip3.writeExternal"); // You must do this: out.writeObject(s); out.writeInt(i); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip3.readExternal"); // You must do this: s = (String) in.readObject(); i = in.readInt(); } public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("Constructing objects:"); Blip3 b3 = new Blip3("A String ", 47); System.out.println(b3); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( "Blip3.out")); System.out.println("Saving object:"); o.writeObject(b3); o.close(); // Now get it back: ObjectInputStream in = new ObjectInputStream(new FileInputStream( "Blip3.out")); System.out.println("Recovering b3:"); b3 = (Blip3) in.readObject(); System.out.println(b3); } }
简要说明:
- 默认构造函数Blip3()的访问控制符需要是public,而Blip3(String x, int a)的访问级别则不受限制;
- 在writeExternal和readExternal中需要显式的进行序列和反序列化;
- 如果从一个类继承于一个Externalizable对象,通常需要在writeExternal和readExternal调用父类中对应的方法;
- 代码中的资源关闭是不安全的;
2、实现Serializable接口 + transient修饰符:
transient关键字会关闭被修饰字段的序列化,从而达到对某些字段进行控制的要求!
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; import java.util.concurrent.TimeUnit; public class Logon implements Serializable { private static final long serialVersionUID = 1805708074792316054L; private Date date = new Date(); private String username; private transient String password; public Logon(String name, String pwd) { username = name; password = pwd; } public String toString() { return "logon info: \n username: " + username + "\n date: " + date + "\n password: " + password; } public static void main(String[] args) throws Exception { Logon a = new Logon("Hulk", "myLittlePony"); System.out.println("logon a = " + a); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( "Logon.out")); o.writeObject(a); o.close(); TimeUnit.SECONDS.sleep(1); // Delay // Now get them back: ObjectInputStream in = new ObjectInputStream(new FileInputStream( "Logon.out")); System.out.println("Recovering object at " + new Date()); a = (Logon) in.readObject(); System.out.println("logon a = " + a); } }
简要说明:
- 代码中的资源关闭是不安全的;
3、实现Externalizable接口的替代方案:实现Serializable + 添加方法:
实现Serializable接口,并添加(不是“覆盖”或者“实现”)以下函数:
- private void writeObject(ObjectOutputStream stream) throws IOException;
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException;
这样做以后,对象的序列化和反序列化会自动的分别调用这两个方法!
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class SerialCtl implements Serializable { private static final long serialVersionUID = -760562456622756361L; private String a; private transient String b; public SerialCtl(String aa, String bb) { a = "Not Transient: " + aa; b = "Transient: " + bb; } public String toString() { return a + "\n" + b; } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeObject(b); } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); b = (String) stream.readObject(); } public static void main(String[] args) throws IOException, ClassNotFoundException { SerialCtl sc = new SerialCtl("Test1", "Test2"); System.out.println("Before:\n" + sc); ByteArrayOutputStream buf = new ByteArrayOutputStream(); ObjectOutputStream o = new ObjectOutputStream(buf); o.writeObject(sc); // Now get it back: ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream( buf.toByteArray())); SerialCtl sc2 = (SerialCtl) in.readObject(); System.out.println("After:\n" + sc2); } }
简要说明:
- 在writeObject函数内,可以调用defaultWriteObject来执行默认的writeObject函数;
- 在readObject函数内,可以调用defaultReadObject来执行默认的readObject函数;
- 上述代码中有一些晦涩难懂的内容,需要查找一些辅助资料来理解;
4、最近在看 《Thinking in Java》, 本文整理自《Thinking in Java》,略有改动!:)
相关推荐
### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的状态转换成字节流的过程,以便于在网络上传输或存储到磁盘上。Java序列化标准定义了一套规则来描述如何...
Java对象序列化是一种将Java对象转换为字节流的过程,以便可以存储在磁盘上、在网络上传输或在任何其他需要持久化数据的场景中使用。这个过程涉及到两个主要概念:序列化(Marshalling)和反序列化(Unmarshalling)...
Java对象序列化是Java平台的一项重要特性,它允许将对象的状态转换为字节流,以便存储、传输或恢复。在本文中,我们将深入探讨关于Java对象序列化你可能不知道的五件事情,这些知识点对于理解和优化你的Java应用程序...
【JAVA对象序列化保存为XML文件的工具类】 在Java编程中,对象序列化是一种将对象的状态转换为字节流的过程,以便可以存储或在网络上传输。而在反序列化时,这个字节流又可以恢复为原来的对象。Java提供了一个方便...
Java对象序列化是一种将对象转换为字节流的过程,以便可以将其存储在磁盘上,或者在网络中进行传输。这是Java平台提供的一种功能,允许程序员将任何Java对象持久化,即将其状态保存到磁盘,或者在网络中进行传输。...
Java对象序列化是Java平台提供的一种机制,允许将对象的状态转换为字节流,以便存储在磁盘上、通过网络传输或在不同时间点恢复。这个过程涉及到将一个复杂的Java对象模型转换为简单的二进制表示,使得数据可以在不同...
Java对象序列化是一种将Java对象转换为字节流的过程,以便可以存储这些对象或通过网络进行传输。这个过程是Java平台的核心特性,它允许开发者将复杂的对象结构持久化或者在网络间进行安全通信。序列化不仅可以用于...
java 序列化和反序列化的方法 Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在...
### Java对象序列化详解 #### 一、Java对象序列化概念 Java对象序列化是指将一个Java对象的状态信息转换成可以存储或传输的形式的过程。在这个过程中,对象的信息被编码成一系列字节,以便可以在文件系统中保存...
1. **Java序列化机制**:Java对象序列化是通过实现`Serializable`接口来标记一个类可被序列化。`ObjectOutputStream`用于将对象写入流,`ObjectInputStream`用于从流中读取并反序列化对象。 2. **易受攻击的库**:...
Java对象序列化是Java开发中的一个重要概念,它允许我们将Java对象转换为字节流,以便存储、传输或在不同时间点恢复。以下是五个可能不为人知的关于Java对象序列化的知识点,这些知识点对于深入理解Java开发至关重要...
C#的XML序列化允许我们控制哪些字段和属性参与序列化,可以通过添加`[XmlElement]`、`[XmlAttribute]`等特性来指定。此外,C#还提供了JSON序列化库如Newtonsoft.Json(Json.NET),它在Web应用中广泛应用,支持更...
前者代表对象输出流,具备`writeObject(Object obj)`方法,可以将对象序列化并写入到目标输出流;后者代表对象输入流,其`readObject()`方法能从输入流中读取字节流并反序列化为对象。 为了使一个Java对象能够被...
总结,Java对象的序列化和反序列化是Java开发中不可或缺的一部分,理解并熟练掌握这些技术可以帮助我们更好地处理数据存储和传输的问题。在实际操作时,应根据具体需求选择合适的方法,并注意相关的安全和性能问题。
Java序列化是Java平台中的一种持久化机制,它允许对象的状态被转换成字节流,以便存储、网络传输或在不同时间点恢复。这个过程被称为序列化,而反向操作称为反序列化。序列化在许多场景下都非常有用,比如在分布式...
通过实现`Serializable`接口,一个Java对象就可以被序列化。这个接口是一个标记接口,没有定义任何方法,仅表示对象支持序列化。 二、为什么需要Java序列化 1. 持久化:序列化可以将对象状态持久化到磁盘,以便下次...
总的来说,Java对象序列化是一个强大的工具,但也需要根据具体的应用场景进行适当的优化。开发者需要平衡性能需求、代码的可读性和维护性,以实现最佳的序列化策略。在考虑优化时,应始终注意性能测试,确保所做的...