先来吐槽下
这两天找实习真是太痛苦了 ,来了大城市才发现优秀的人真的很多,自己不努力就会落后,今天群里的一个小哥哥说当年他面试阿里的时候第一道面试题就是序列化是什么,id什么作用 ,我才发现 学了这么久我连序列化是什么都不知道 ,人和人的差距呀,惭愧惭愧, 当年要是早点醒悟好好学习 ,现在也不至于找个实习这么难了。好啦 吐槽完了。下面说一下什么是序列化。
一、什么是序列化
他可以将对象以二进制的方式保存在文件、磁盘或者其他其他地方 ,说白了就是将对象数据持久化,一般来说java对象保存在内存中,JVM处于运行时这些数据才会存在,不运行时数据会消失,但是这些数据我们以后可能还会用到 ,这怎么办 ,此时我们就需要将这些数据序列化了。还有比如当我们在网络上传递数据 都会用到序列化,他会通过远程的方法将数据传输过去。
举个小例子吧 包装类型的数据和枚举类型的数据都实现了序列化接口
这个属性类型 似乎基本类型的数据也可以实现序列化,反正我写是没有问题的
package zhan;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private Integer age;
public Student(){
System.out.println("默认构造方法");
}
public Student(String name, int age) {
super();
System.out.println("重载构造方法");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//重写toString方法
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
程序输出
package zhan;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Test {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
File file=new File("d://ser.txt");
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(file));
Student student=new Student("小明",1);
out.writeObject(student);
out.close();
ObjectInputStream input=new ObjectInputStream(new FileInputStream(file));
Object newStudent = input.readObject();
System.out.println(newStudent);
input.close();
}
}
输出结果
重载构造方法
Student [name=小明, age=1]
*当一个类实现了序列化,在类本身里面引用的非序列化对象都会被序列化 ,但是这会造成开销大
二、 还有一个重点 ,当想要序列化的数据里面有比较隐私的数据 那么我们可以采用这样的方式来 存储
1.transient关键字
我将上面的属性其中一个加上transient关键字 其他不变输出结果变为
重载构造方法
Student [name=小明, age=null]
如果age为int类型 输出为0
2.Externalizable接口
结果为
重载构造方法
默认构造方法
Student [name=null, age=null]
三、id值是干什么的
private static final long serialVersionUID = -5809782578272943999L; 有时候你可能会见到这个值 这个就是id值
他象征的的 序列化的版本一样 ,如果第一次你将某些值序列化了 ,后来你将属性改了几个 并且还从原来的地方取值 这时 由于id值不一样,那么反序列化会失败因为两次id值不一样
第一次我只将name值序列化 ,但是我从却要从存储文件中取name和age值 然后报错
Exception in thread "main" java.io.InvalidClassException: zhan.Student; local class incompatible: stream classdesc serialVersionUID = -4928308139594497146, local class serialVersionUID = 1216654284640239673
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at zhan.Test.main(Test.java:21)
从错误能看出两次id值是不一样的
浅谈就到这里啦
有一些不足的地方希望大佬们能提出来
联系qq:2521340635