Java对象的序列化与反序列化
2016-05-01 15:54
501 查看
序列化与反序列化
序列化就是将对象的状态信息转换为可以存的字节序列存等储,在以后将这个字节序列恢复成对象就是反序列化。
实现Serializable的方式
public class Fruit implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String name; private int size; /** * @param name * @param size */ public Fruit(String name, int size) { super(); this.name = name; this.size = size; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } @Override public String toString() { return "Fruit [name=" + name + ", size=" + size + "]"; } }
public static void main(String[] args) throws IOException, ClassNotFoundException { Fruit fruit = new Fruit("banana", 100); ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream stream = new ObjectOutputStream(out); stream.writeObject(fruit); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); Fruit fruitRecover = (Fruit) in.readObject(); System.out.println(fruitRecover); }
输出:
Fruit [name=banana, size=100]
上面的例子中可以自定义读和写方法,如果有则调用自己的方法在Fruit中加入
private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException { in.defaultReadObject(); //可以用自己的逻辑读数据 System.out.println("readObject"); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); //可以用自己的逻辑写数据 System.out.println("writeObject"); }
注意点
尽量在需要序列化的类中定义序列serialVersionUID ,否则虚拟机将自动调用方法实现一个序列,影响性能。transient关键字的字段无法实现序列。
静态成员属于类级别的,所以不能序列化,除非你都在同一个机器(而且是同一个进程),且jvm已经把字段加载进来了。
实现Externalizable的方式
这种方法必须要自己实现读和写,并且必须要有无参数构造器,看下代码public class Person implements Externalizable { private String name; private int age; public Person() { super(); System.out.println("default constructor"); } public Person(String name, int age) { super(); this.name = name; this.age = age; System.out.println("params constructor"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeInt(age); System.out.println("writeExternal"); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); age = in.readInt(); System.out.println("readExternal"); } }
public static void testES() throws IOException, ClassNotFoundException { Person person = new Person("zzh", 20); ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream stream = new ObjectOutputStream(out); stream.writeObject(person); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); Person p = (Person) in.readObject(); System.out.println(p.getAge()); }
输出:
params constructor
writeExternal
default constructor
readExternal
20
一些使用场景
在一些网络传输、RMI等远程传输。tomcat在重启时,也会将session中的对象序列化,我们不需要重新登录。
使用jrdis保存对象时也能用到。
参考
《Java编程思想》http://www.hollischuang.com/archives/1150
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树