一般默认情况对对象进行序列化时会选择使用Serializable接口即可以了,而且Serializable接口不仅能序列化自己显示写进去的对象,而且会自动的追踪对象内的所包含的对象的引用,并且是迭代追踪的,省却了许多麻烦。
不过如果在对象进行序列化时如果希望对对象的某些部分不被序列化(其实也可以用transient关键字解决)或者在对象被反序列化时希望某些子对象或属性可以重建的话,那么就可以用另一种序列化方式:实现Externalizable接口,即可方便的解决这些问题,下面对这两种方式分别举例说明:
SerializableTest.java:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class A implements Serializable{
private int id;
private String name;
public A(){
}
public A(int id,String name){
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
public class SerializableTest {
public static void main(String[] args) throws IOException,ClassNotFoundException{
A a=new A(3,"test");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("test.out"));
oos.writeObject(a);
oos.close();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("test.out"));
Object o=ois.readObject();
System.out.println(o.getClass());
A a1=(A)o;
System.out.println(" "+a1.getId()+":"+a1.getName());
}
}
上面的示例程序即时对serializable序列化机制的简单演示,其实serializable序列化实现是先将需要序列化的对象给转化成相应的二进制,然后存储到相应的硬盘设备或文件中,再反序列化时再完全以文件上的二进制位为基础构造出被序列化的对象,而不会涉及的对象的构造函数,数据均是从InputStream中获取的。
Externalizable序列化机制和Serializable有所不同,首先实现Externalizable接口必须要实现writeExternal(ObjectOutput out) 和void readExternal(ObjectInput in)两个方法,这两个方法分别在对象被序列化和反序列化时自动调用,可以从下面的示例中看出,而且Externalizable的反序列化和serializable不一样,它会在反序列化时调用对象的默认构造函数来创建这个对象,然后利用void readExternal(ObjectInput in)中的对相应的属性的进行初始化。如果没有该默认构造函数,会报错。
ExternalizableTest.java:
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;
class B implements Externalizable{
private int id;
private String name;
//如果没有默认构造函数时,会在反序列化时报错
public B(){
System.out.println("default Constructor called!");
}
public B(int id,String name){
System.out.println("Constructor called!");
this.id=id;
this.name=name;
}
//会在进行改对象的反序列化时被自动调用,这样可以在该方法中根据自要求有选择性的对子对象或者某些属性进行构建或读取
//如果没有对该方法中的属性(如下方法中的id和name进行初始化的话,那么id就会为0,name为null)
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// TODO Auto-generated method stub
System.out.println("readExternal finished!");
id=in.readInt();
name=(String)in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
// TODO Auto-generated method stub
System.out.println("writeExtern finished!");
out.writeInt(id);
out.writeObject(name);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ExternalizableTest {
public static void main(String[] args) throws IOException,ClassNotFoundException{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("testb.out"));
B b=new B(1,"test");
oos.writeObject(b);
oos.close();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("testb.out"));
B b1=(B)ois.readObject();
System.out.println(" "+b1.getId()+":"+b1.getName());
}
}
程序运行结果如下:
Constructor called!
writeExtern finished!
default Constructor called!
readExternal finished!
1:test
可以看出这两种序列化的一些区别。
分享到:
相关推荐
2. **自定义序列化**:通过实现Externalizable接口,自定义序列化和反序列化逻辑,适合需要优化性能或有特殊需求的场景。 3. **序列化过滤**:使用`transient`关键字忽略不想序列化的字段,或使用`@serialData`注解...
* 使用 Externalizable 接口实现序列化和反序列化 * 使用 Java 序列化 API 实现序列化和反序列化 在实际开发中,选择合适的序列化和反序列化方法取决于具体的需求和场景。在本例中,我们使用 Serializable 接口实现...
`Externalizable`接口允许对象完全控制序列化过程,而仅实现`Serializable`接口的类则采用默认的序列化方式。对于那些不希望被序列化的类或字段,可以使用`transient`或`volatile`关键字标记,它们会被忽略在序列化...
2. **实现Externalizable接口**:这个接口继承自`Serializable`,提供了更高级别的控制,允许开发者自己编写序列化逻辑。 3. **序列化兼容性**:`serialVersionUID`的作用在于保证版本兼容性。开发者可以通过显式...
### Java.io.Serializable 序列化...通过实现 `Serializable` 接口或 `Externalizable` 接口,可以轻松地实现序列化和反序列化功能。需要注意的是,在实际应用中还需要考虑序列化的效率、安全性以及版本兼容性等问题。
总结来说,Java中的序列化和反序列化是通过`Serializable`接口和`Externalizable`接口来实现的。`Serializable`接口是默认的序列化方式,适用于大多数简单情况;而`Externalizable`接口则提供了自定义序列化行为的...
1)Serializable和Externalizable接口Xstream框架2)Simple框架 3)Apache的AXIOM框架 2、XML验证文档的生成工具 trang.jar 3、利用XSD文件的XML3种验证方法 1)Dom4j的SAXValidator (dom4j.jar, javax.xml....
另外,还有`java.io.Externalizable`接口,它继承自`Serializable`,但提供了更细粒度的控制权,允许类自定义序列化和反序列化的行为。如果一个类实现了`Externalizable`,则需要手动实现`writeExternal...
通过实现`Serializable`或`Externalizable`接口,我们可以控制对象如何被序列化和反序列化,同时`transient`关键字提供了保护敏感数据的手段。理解和熟练运用这些概念对于Java开发者来说非常重要,特别是在处理持久...
7. **序列化优化**:讨论了如何通过实现Externalizable接口来自定义序列化行为,以及使用writeObject和readObject方法优化序列化过程。 8. **序列化版本ID**:讲解了serialVersionUID字段的重要性,用于确保反序列...
### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的...以上内容涵盖了Java序列化标准的关键知识点,深入了解这些概念有助于更好地理解和应用Java序列化技术。
4. **Externalizable接口**:除了`Serializable`接口,还可以选择实现`Externalizable`接口,这是一个更细粒度的控制序列化过程的方法。实现这个接口需要提供`writeExternal()`和`readExternal()`方法,由程序员自己...
- **Externalizable**:继承自Serializable接口,提供更细粒度的控制,允许开发者自定义序列化和反序列化的行为。 4. **序列化和反序列化步骤** - **序列化**: - 创建`ObjectOutputStream`,可以传入一个其他...
Java文件序列化是Java平台中一种重要的数据存储和交换机制,它允许我们将对象的状态转换为字节流,以便可以保存到磁盘、网络传输或在内存中存储,然后在需要时将这些字节流恢复为原来的对象。这个过程称为序列化...
在这种情况下,可以考虑使用`writeObject()`和`readObject()`方法来自定义序列化行为,或者使用`Externalizable`接口,它比`Serializable`提供了更多的控制。 6. **序列化框架**:除了Java内置的序列化机制,还有...
实现`Externalizable`的类必须提供`readExternal()`和`writeExternal()`方法,手动控制序列化和反序列化过程。 7. **对象流的用途**: - 数据持久化:将对象状态保存到磁盘,以便程序重新启动后恢复。 - 网络传输...
序列化也可能带来安全风险,因为任何实现了Serializable接口的对象都可以被序列化,然后在不受信任的环境中反序列化。这种攻击称为“反序列化漏洞”,可能导致代码执行。因此,谨慎处理反序列化的对象,避免来自不可...