Serializable的使用常见问题:
1. 不加 serialVersionUID 与serialVersionUID的作用
serialVersionUID 通常用于对象的版本控制 如果在数据结构发生改变时 会出现反序列化失败
eg:先使用序列化 存储了一个对象
image.png
static class User implements Serializable {
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String name;
public int age;
//新增nickName 字段
public String nickName;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", nickName=" + nickName +
'}';
}
}
再读一次序列化文件,哦吼翻车:
修改数据结构后读取序列化文件.png
解决方式:加上 serialVersionUID
加上serialVersionUID后.png
2. 部分字段不需要序列化 使用transient关键字
static class User implements Serializable {
public User(){
System.out.println("=============");
}
public User(String name, int age) {
System.out.println("==============");
this.name = name;
this.age = age;
}
public String name;
public int age;
public transient String nickName;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", nickName=" + nickName +
'}';
}
}
public static void main(String[] args) {
trasientTest();
}
private static void trasientTest() {
User user = new User("salt fish", 18);
user.nickName = "芭比龙";
System.out.println("1: " + user);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
byte[] userData = null;
try {
oos = new ObjectOutputStream(out);
oos.writeObject(user);
userData = out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new ByteArrayInputStream(userData));
user = (User)ois.readObject();
System.out.println("反序列化后 2: " + user);
} catch (Exception e) {
e.printStackTrace();
}
}
打印结果:
1: User{name='salt fish', age=18, nickName=芭比龙}
反序列化后 2: User{name='salt fish', age=18, nickName=null}
3. 序列化的类中有未序列化的成员 时会序列化失败 必须成员实现序列化接口
4. 类序列化但是父类未序列化
static class Person{
private String sex;
private int id;
public Person() {
}
public Person(String sex, int id) {
this.sex = sex;
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"sex='" + sex + '\'' +
", id=" + id +
'}';
}
}
static class User extends Person implements Serializable {
public User(String name, int age,String sex,int id) {
super(sex,id);
this.name = name;
this.age = age;
}
public User(){
super();
};
public String name;
public int age;
//重写方法
private void writeObject(ObjectOutputStream out) throws IOException {//不是重写父类的方案
out.defaultWriteObject();
out.writeObject(getSex());
out.writeInt(getId());
}
//重写方法
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
setSex((String)in.readObject());
setId(in.readInt());
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
"} " + super.toString();
}
}
5. 父类可序列化 子类不想序列化
static class Person implements Serializable {
private static final long serialVersionUID = 5850510148907441688L;
private String sex;
private int id;
public Person() {
}
public Person(String sex, int id) {
this.sex = sex;
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"sex='" + sex + '\'' +
", id=" + id +
'}';
}
}
static class User extends Person {
public User(String name, int age, String sex, int id) {
super(sex, id);
this.name = name;
this.age = age;
}
public String name;
public int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
"} " + super.toString();
}
}
static class User1 extends Person {
public User1(String name, int age, String sex, int id) {
super(sex, id);
this.name = name;
this.age = age;
}
public String name;
public int age;
//子类不想被序列化的处理方式
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
throw new NotSerializableException("Can not serialize this class");
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new NotSerializableException("Can not serialize this class");
}
private void readObjectNoData() throws ObjectStreamException {
throw new NotSerializableException("Can not serialize this class");
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
"} " + super.toString();
}
}
6. 序列化单例类
class Singleton implements Serializable{
public static Singleton INSTANCE = new Singleton();
private Singleton(){}
//这里返回单例实例
private Object readResolve(){
return INSTANCE;
}
}