java序列化一定要应该注意的6个事项!
2016-06-23 18:27
288 查看
1、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。
2、静态变量不会被序列化,那是类的“菜”,不是对象的。
3、transient关键字修饰变量可以限制序列化。
4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,就是 private static final long serialVersionUID = 1L。
5、Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。
6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。读者在使用一个文件多次 writeObject 需要特别注意这个问题(基于第5点)。
转载请注明—作者:Java我人生(陈磊兴)
序列化保存的是对象的状态,而静态变量是类的状态。
1、基本类型的数据可以直接序列化
2、对象要被序列化,它的类必须要实现Serializable接口;如果一个类中有引用类型的实例变量,这个引用类型也要实现Serializable接口。
3、可以用这个代码:ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria"));
但是不能用这个代码:ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria",true));
4、如果对象的引用类型没有实现序列化,但是还是想将这个对象序列化,那么可以将对象中用到的那个引用类型对象设置为transient类型。
(如果A包含了对B的引用,那么在序列化A的时候也会将B一并地序列化;如果此时A可以序列化,B无法序列化,那么在序列化A的时候就会发生异常,这时就需要将对B的引用设为transient,该关键字表示变量不会被序列化。)
5、如果用transient修饰引用类型对象,则这个引用类型的对象不会保存,那么如果希望保存下来又如何实现呢?
用这两段儿代码:
[java] view
plain copy
//这个方法会在序列化的过程中被调用
private void writeObject(ObjectOutputStream out){
try {
out.defaultWriteObject(); //这个方法会把这当前中非静态变量和非transient变量写到流中
//在这里我们就把name写到了流中。
//因为我们要保存Book的状态,所以我们还要想办法把其状态写入流中
out.writeInt(book.getIsbn());//ObjectOutputStream中提供了写基本类型数据的方法
//out.close();//注意,这句千万不能有,否刚将直接导致写入失败
} catch (IOException e) {
e.printStackTrace();
}
}
//这个方法会在反序列化的过程中被调用
private void readObject(ObjectInputStream in){
try {
in.defaultReadObject(); //和defaultWriteObject()方法相对应,默认的反序列化方法,会从流中读取
//非静态变量和非transient变量
int isbn = in.readInt(); //用这个方法来读取一个int型值,这里我们是读取书号
book = new Book(isbn); //这里我们就通过读取的 保存的状态构造 了一个和原来一样的Book对象
//in.close();同样的这句也不能有
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
6、如果一个类没有实现Serializable接口,但是它的父类实现了,那么这个类也可以序列化。
7、如果一个类实现了Serializable接口,但是它的父类没有实现,那么这个类可以进行序列化吗?
答案是可以的,因为超类Object类没有实现Serializable接口,所以你懂了吧,但是会有个问题,你需要在父类中是实现默认的构造方法,否则会报异常:no validconstructor。
2、静态变量不会被序列化,那是类的“菜”,不是对象的。
3、transient关键字修饰变量可以限制序列化。
4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,就是 private static final long serialVersionUID = 1L。
5、Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。
6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。读者在使用一个文件多次 writeObject 需要特别注意这个问题(基于第5点)。
转载请注明—作者:Java我人生(陈磊兴)
序列化保存的是对象的状态,而静态变量是类的状态。
1、基本类型的数据可以直接序列化
2、对象要被序列化,它的类必须要实现Serializable接口;如果一个类中有引用类型的实例变量,这个引用类型也要实现Serializable接口。
3、可以用这个代码:ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria"));
但是不能用这个代码:ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria",true));
4、如果对象的引用类型没有实现序列化,但是还是想将这个对象序列化,那么可以将对象中用到的那个引用类型对象设置为transient类型。
(如果A包含了对B的引用,那么在序列化A的时候也会将B一并地序列化;如果此时A可以序列化,B无法序列化,那么在序列化A的时候就会发生异常,这时就需要将对B的引用设为transient,该关键字表示变量不会被序列化。)
5、如果用transient修饰引用类型对象,则这个引用类型的对象不会保存,那么如果希望保存下来又如何实现呢?
用这两段儿代码:
private transient Book book;//用transient关键字声明book
[java] view
plain copy
//这个方法会在序列化的过程中被调用
private void writeObject(ObjectOutputStream out){
try {
out.defaultWriteObject(); //这个方法会把这当前中非静态变量和非transient变量写到流中
//在这里我们就把name写到了流中。
//因为我们要保存Book的状态,所以我们还要想办法把其状态写入流中
out.writeInt(book.getIsbn());//ObjectOutputStream中提供了写基本类型数据的方法
//out.close();//注意,这句千万不能有,否刚将直接导致写入失败
} catch (IOException e) {
e.printStackTrace();
}
}
//这个方法会在反序列化的过程中被调用
private void readObject(ObjectInputStream in){
try {
in.defaultReadObject(); //和defaultWriteObject()方法相对应,默认的反序列化方法,会从流中读取
//非静态变量和非transient变量
int isbn = in.readInt(); //用这个方法来读取一个int型值,这里我们是读取书号
book = new Book(isbn); //这里我们就通过读取的 保存的状态构造 了一个和原来一样的Book对象
//in.close();同样的这句也不能有
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
6、如果一个类没有实现Serializable接口,但是它的父类实现了,那么这个类也可以序列化。
7、如果一个类实现了Serializable接口,但是它的父类没有实现,那么这个类可以进行序列化吗?
答案是可以的,因为超类Object类没有实现Serializable接口,所以你懂了吧,但是会有个问题,你需要在父类中是实现默认的构造方法,否则会报异常:no validconstructor。
相关文章推荐
- java虚拟机之线程同步
- java多线程--AtomicLong和LongAdder
- 代理模式(Proxy) Java
- PKAV 发现 Struts2 最新远程命令执行漏洞(S2-037)
- 2016.6.23笔记(2)-本地配置
- spring定时任务.线程池,自定义多线程配置
- Java中的byte[]/char[]/int/String数据类型转换
- JAVA 数组的初始化
- Struts2跳转结果页时没有css样式或图片的问题
- Java synchronized的使用
- 触发Full GC执行的情况
- RxJava 学习笔记(二)
- Spring声明式事务管理与配置介绍
- java.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' 异常处理,及MySQL数据库编码设置
- 浅析Java中的final关键字
- java中将一个字符数组赋值给另一个,两者同时变化
- Spring MVC程序中怎么得到静态资源文件css,js,图片文件的路径问题
- JAVA实现DES加密实现详解
- javaweb中文件上传下载示例
- JS加密Java解密报rsa bad argument