不算难理解
序列化和反序列化这两个名词很早就从 Java 的反序列化漏洞里听过了
但当时由于实力不足,不知道是什么意思,也就很懵逼的过去了
今天学了序列化和反序列化,理解起来不算难吧
ObjectOutputStream 序列化
把 Java 中实例化的对象转换为字节数据,这样就能把它存储起来,这样以后要用的时候就不用在 new 一个对象了
也可以把这个序列化后的数据通过网络发送到其他电脑上,这样别的电脑就可以使用这个类了
使用方法:
1 2 3 4 5 6
| FileOutputStream fos = new FileOutputStream("person.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); Person ren = new Person("mua", 10); oos.writeObject(ren); fos.close(); oos.close();
|
然后就会发现多了一个 person.txt 的文件,但由于编码问题,看到的是乱码
对象实例化后产生的文件可以通过反序列化变回一个对象
变回的对象都是 Object 类的对象,需要转换一下
1 2 3 4 5
| ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt")); Object o = ois.readObject(); ois.close(); Person ren = (Person) o; System.out.println(ren);
|
存储和读取多个对象
可以用 ArrayList 来创建一个对象的数组,然后存储起来,反序列化的时候用 ArrayList 接收
1 2 3 4 5 6 7
| ArrayList<Person> arr = new ArrayList<>(); arr.add(new Person("Wife", 16)); arr.add(new Person("Sister", 14));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.txt")); oos.writeObject(arr); oos.close();
|
反序列化多个对象
1 2 3 4 5 6 7
| ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt")); Object o = ois.readObject(); ArrayList<Person> per = (ArrayList<Person>) o; for (Person person : per) { System.out.println(person); } ois.close();
|
序列化类的定义
如果一个类所创建的对象要实现序列化,就要继承 Serializable 接口,这个接口里面什么方法都没有,之所以继承只是为了标记这个类是可序列化的
1 2 3
| public class Person implements Serializable{ static final long serialVersionUID = 100; }
|
一个类如果可以被序列化,那么就可以根据这个类的定义算出它的序列id,类似于进行了一次hash运算
如果对类进行了修改,这个id就会不一样,反序列化的时候需要用到这个id,如果id不一样就会反序列化失败
此时如果在定义类的时候固定这个id,就不会有这种困难了
serialVersionUID 必须加上static final 这两个修饰符
transient和static修饰符很像,它们定义的参数都不能参加序列化
transient只是不参加序列化,它没有static的可以不实例化类就调用的特性
马上就可以开始学习网络编程了,虽然之前学过 Python 的网络编程,但两个语言的差别还是挺大的,还是要好好学
马上要放暑假了,回家可以边学 Java,边学学 Linux 开发 (⸝⸝•‧̫•⸝⸝)