被序列对象(bean)实现Serializable或Externalizable接口,
实现Serializable接口的对象可以序列化除静态变量和被transient修饰的属性。
PS:如果发现静态变量可以被序列化的假象,其实是JVM中的值,可以在序列化与反序列代码中重设静态变量值证明。
Externalizable接口为Serializable的子接口,其中有两个方法
writeExternal(ObjectOutput out)
readExternal(ObjectInput in)
在练习中发现
public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(this); }
无法读取其完整属性,或出现类型错误。所以说如果想一次序列化所有属性,而不是在实现一行行把所有属性都读写,还是用Serializable接口。简而言之,就是根据你想序列化和不想序列化属性的多少来决定用Serializable还是Externalizable接口。
言归正传,Externalizable接口中的方法可以实现静态变量和被transient(Externalizable中也能用,然并卵)修饰的属性的序列化。
PS:当你实现读属性时可以不注意代码的顺序
public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(stuAge); out.writeObject(stuLength); out.writeObject(stuName); out.writeObject(MAYBE); }但是实现写方法时,就要注意代码顺序,不然会出现类型转换错误(ClassCastException)哦。
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.stuAge = (Integer) in.readObject(); this.stuLength = (Float) in.readObject(); this.stuName = (String) in.readObject(); this.MAYBE = (String ) in.readObject(); }
毕竟一直在对一个对象进行操作。至于重排序可能会出现的状况,谁知道呢,等学\遇到再说吧。
当然你也可以在实现读的时候就指定类型比如readInt(),readFloat()等,然而可能会出现OptionalDataException,
至于原因请转看http://jianghuguke.iteye.com/blog/939786
最后上代码:
main
import java.io.*;
/**
* Created by T1 on 2018/3/17.
*/
public class Main{
public static void main(String[] args) throws IOException {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("C:\\Users\\T1\\Desktop\\112\\1.txt"));
StuBean stu = new StuBean("t1",18,20);
outputStream.writeObject(stu);
outputStream.flush();
outputStream.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\T1\\Desktop\\112\\1.txt"));
stu.setMAYBE("321");//测试静态变量
Object obj = null;
try {
obj = ois.readObject();
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(obj);
}
}
bean
package gysh;
import java.io.*;
public class StuBean implements Externalizable{
private String stuName;
private int stuAge;
private transient float stuLength;
private static String MAYBE = "s1";
public static void setMAYBE(String MAYBE) {
StuBean.MAYBE = MAYBE;
}
public StuBean() {
}
public StuBean(String stuName, int stuAge, float stuLength) {
this.stuName = stuName;
this.stuAge = stuAge;
this.stuLength = stuLength;
}
public float getStuLength() {
return stuLength;
}
public void setStuLength(float stuLength) {
this.stuLength = stuLength;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return MAYBE + "name is: "+getStuName()+" and age is:"+getStuAge()+" but length is:"+getStuLength();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(stuAge);
out.writeObject(stuLength);
out.writeObject(stuName);
out.writeObject(MAYBE);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.stuAge = (Integer) in.readObject();//注意大小顺序,不然ClassCastException
this.stuLength = (Float) in.readObject();
this.stuName = (String) in.readObject();
this.MAYBE = (String ) in.readObject();
}
}Last but not least
作者能力有限,如有遗漏或错误还望指出,谢谢!

本文探讨了Java中的序列化接口Serializable和Externalizable的区别。Serializable接口默认序列化对象的所有属性,除了静态变量和被transient修饰的字段。而实现Externalizable接口允许自定义序列化和反序列化过程,但可能导致类型错误或需要额外处理静态变量。建议根据需要序列化的属性数量选择适合的接口。同时,实现Externalizable的read方法时要注意属性顺序,不正确的顺序可能导致问题。
642

被折叠的 条评论
为什么被折叠?



