标签:sed 否则 也会 避免 txt 子类 静态变量 version 区别
对象序列化的目标是将对象保存在磁盘中或者在网络中进行传输。实现的机制是允许将对象转为与平台无关的二进制流。java中对象的序列化机制是将允许对象转为字节序列。这些字节序列可以使Java对象脱离程序存在,从而可以保存在磁盘上,也可以在网络间传输。对象的序列化是将一个Java对象写入IO流;与此对应的,反序列化则是从IO流中恢复一个Java对象。要将一个java对象序列化,那么对象的类需要实现Serializable或者Externalizable接口。
public class Person implements Serializable { private String name; private transient int salary; private static String country; // getter & setter ... } public class Test { public static final String path = "D:\\object.txt"; public static void main(String[] args) { Person person = new Person(); serialize(person, path); deSerialize(path); } public static void serialize(Person person, String path) { try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path)); oos.writeObject(person); oos.close(); } catch (Exception e) { e.printStackTrace(); } } public static Person deSerialize(String path) { Person person = null; try { ObjectInputStream oos = new ObjectInputStream(new FileInputStream(path)); person = (Person) oos.readObject(); oos.close(); } catch (Exception e) { e.printStackTrace(); } return person; } }
外部序列化与序列化的主要区别在于序列化是内置的API,只需实现Serializable接口,不需要编写任何代码就可以实现对象的序列化,而使用外部序列化时,Externalizable接口中的方法必须由开发人员实现。因此与实现Serializable接口的方法相比,使用Externalizable编写程序的难度更大但编程时可灵活控制需要持久化的属性。当执行外部序列化时,static静态变量也被序列化了。
public class Person implements Externalizable { private String name; private transient int salary; private static String country; @Override public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException { name = (String)in.readObject(); salary = (Integer)in.readObject(); country = (String)in.readObject(); } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeObject(country); } // getter & setter ... } public class Test { public static final String path = "D:\\object.txt"; public static void main(String[] args) { Person person = new Person(); serialize(person, path); deSerialize(path); } public static void serialize(Person person, String path) { try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path)); oos.writeObject(person); oos.close(); } catch (Exception e) { e.printStackTrace(); } } public static Person deSerialize(String path) { Person person = null; try { ObjectInputStream oos = new ObjectInputStream(new FileInputStream(path)); person = (Person) oos.readObject(); oos.close(); } catch (Exception e) { e.printStackTrace(); } return person; } }
每个可序列化的类都有一个都有一个唯一的标识号与其关联,也就是我们通常说的 serialVersionUID。如果可序列化的类没有显示的声明该常量,Java 虚拟机会自动根据这个类调用一个复杂的运算过程,从而产生运行时的 serialVersionUID。这个自动生成的值将会受到类名、实现的接口名称、以及所有的公有方法和受保护的成员名称所影响。如果你通过任何方式改变了这些信息,兼容性都会遭到破坏,在运行时会导致 InvalidClassException 异常。
执行序列化和反序列化时有可能会遇到JRE版本问题。尤其是在网络的两端进行通信时,这种情况更为多见。如果你没有显示的声明 serialVersionUID,就算类的信息没有发生改变,不同 Java 虚拟机序列化的实现方式上可能有所不同,这些细微的差别都有可能导致运行时生成的 serialVersionUID 不一致从而导致反序列化失败。
为了解决这种问题,Java允许为序列化的类提供一个serialVersionUID的常量标识该类的版本。只要serialVersionUID的值不变,Java就会把它们当作相同的序列化版本。自定义serialVersionUID主要由如下3个优点。
关于对象的序列化,总结下注意事项:
参考文章:
http://www.cnblogs.com/amunote/p/4171799.html
http://www.cnblogs.com/zhanglei93/p/5890212.html
标签:sed 否则 也会 避免 txt 子类 静态变量 version 区别
原文地址:http://www.cnblogs.com/anxiao/p/6700681.html