Java 的序列化 (Serializable)(Day_09)
我们的火,要把世界都点燃
运行环境
JDK8 + IntelliJ IDEA 2018.3
什么是序列化,反序列化
序列化是将对象状态转换为可保持或传输的格式的过程。
与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
反序列化是指将存储在存储媒体中的对象状态装换成对象的过程
序列化的作用
- 以某种存储形式使自定义对象持久化;
- 将对象从一个地方传递到另一个地方。
- 保证对象的完整性和可传递性。
- 使程序更具维护性
如何实现类的序列化?
实现Serializable接口
编程实现类的序列化:
1 关键代码
2 public static void main(String[] args) throws Exception{
3
4 Student stu = new Student();
5
6 File file = new File("bb.dat");
7
8 ObjectOutputStream oos = new ObjectOutputStream(new
9
10 FileOutputStream(file));
11
12 oos.writeObject(stu);
13 }
编程实现类的反序列化:
1 public static void main(String[] args) throws Exception{
2
3 File file = new File("bb.dat");
4
5 ObjectInputStream ois = new ObjectInputStream(new
6
7 FileInputStream(file));
8
9 Object obj = ois.readObject();
10
11 System.out.println(obj.hashCode());
12 }
多对象Serializable(序列化)的实现
序列化鱼,还需要序列化鱼的生存环境---水。
1 //环境: 水
2 import java.io.Serializable;
3
4 public class Water implements Serializable {
5 int opacity;
6
7 public Water(int opacity) {
8 this.opacity = opacity;
9 }
10
11 public Water() {
12 }
13
14 @Override
15 public String toString() {
16 return "Water{" +
17 "opacity=" + opacity +
18 '}';
19 }
20 }
1 import java.io.Serializable;
2
3 public class Fish implements Serializable {
4
5 String color;
6 String type;
7 Water enviroment;
8
9 public Fish(String color, String type, Water enviroment) {
10 this.color = color;
11 this.type = type;
12 this.enviroment = enviroment;
13 }
14
15 public Fish(String color, String type) {
16 this.color = color;
17 this.type = type;
18 }
19
20 public Fish() {
21 }
22
23 @Override
24 public String toString() {
25 return "Fish{" +
26 "color='" + color + '\'' +
27 ", type='" + type + '\'' +
28 ", enviroment=" + enviroment +
29 '}';
30 }
31 }
import java.io.*;
// 序列化
public class TestFish {
public static void main(String[] args) {
Water enro = new Water(99);
Fish fish = new Fish("金色", "鲤鱼", enro); File file = new File("fish.bat");
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
oos.writeObject(fish); oos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} // 反序列化
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream; public class TestFish2 {
public static void main(String[] args) {
try {
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("fish.bat"));
try {
Fish fish=(Fish) objectInputStream.readObject();
System.out.println(fish);
objectInputStream.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
¤ transient关键字:将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会被序列化。
- 浅克隆 —— 只克隆本身
被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然只指向原来的对象。
代码演示:
1 package com.wenhaitao.yxdemo.demo4;
2 public class Professor {
3 String name;
4 int age;
5
6 public Professor(String name, int age) {
7 super();
8 this.name = name;
9 this.age = age;
10 }
11
12 public Professor() {
13 super();
14 }
15
16 @Override
17 public String toString() {
18 return "Professor [age=" + age + ", name=" + name + "]";
19 }
20
21 }
1 // 浅克隆 2
3 public class Student implements Cloneable {
4 String name;
5 int age;
6
7 Professor p;
8
9 public Professor getP() {
10 return p;
11 }
12
13 public void setP(Professor p) {
14 this.p = p;
15 }
16
17 @Override
18 public Object clone() throws CloneNotSupportedException {
19 return super.clone();
20 }
21
22 public Student() {
23 super();
24 }
25
26 public Student(String name, int age) {
27 super();
28 this.name = name;
29 this.age = age;
30 }
31
32 public Student(String name, int age, Professor p) {
33 super();
34 this.name = name;
35 this.age = age;
36 this.p = p;
37 }
38
39 @Override
40 public String toString() {
41 return "Student [age=" + age + ", name=" + name + ", p=" + p + "]";
42 }
43
44 public static void main(String[] args) throws CloneNotSupportedException {
45 Professor p = new Professor("feifeiye",50);
46 Student s1 = new Student("zhangsan", 19, p);
47 Student s2 = (Student) s1.clone();
48 System.out.println(s1);
49 System.out.println(s2);
50 System.out.println(s1==s2);
51
52 s2.p.name = "wangwu";
53 s2.p.age = 90;
54 System.out.println(s2);
55 System.out.println(s1);
56 }
57 }
- 深克隆 —— 克隆本身和所有的成员
概述:
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量,
那些引用其他对象的变量将指向被复制过的新对象,而不再指向原有的那些被引用的对象,
换言之,深复制把要复制的对象所引用的对象都复制了一遍。
代码演示:
1 2 public class Professor implements Cloneable{
3 String name;
4 int age;
5
6 public Professor(String name, int age) {
7 super();
8 this.name = name;
9 this.age = age;
10 }
11
12 public Professor() {
13 super();
14 }
15
16 public Object clone() throws CloneNotSupportedException {
17 return super.clone();
18 }
19
20
21 @Override
22 public String toString() {
23 return "Professor [age=" + age + ", name=" + name + "]";
24 }
25
26 }
1 //深克隆
2 public class Student implements Cloneable {
3 String name;
4 int age;
5
6 Professor p;
7
8 public Professor getP() {
9 return p;
10 }
11
12 public void setP(Professor p) {
13 this.p = p;
14 }
15
16 @Override
17 public Object clone() throws CloneNotSupportedException {
18 Object obj = super.clone();
19 Student s = (Student) obj;
20 s.p = (Professor) this.p.clone();
21 return obj;
22 }
23
24 public Student() {
25 super();
26 }
27
28 public Student(String name, int age) {
29 super();
30 this.name = name;
31 this.age = age;
32 }
33
34 public Student(String name, int age, Professor p) {
35 super();
36 this.name = name;
37 this.age = age;
38 this.p = p;
39 }
40
41 @Override
42 public String toString() {
43 return "Student [age=" + age + ", name=" + name + ", p=" + p + "]";
44 }
45
46 public static void main(String[] args) throws CloneNotSupportedException {
47 Professor p = new Professor("肥肥也",19);
48 Student s1 = new Student("都一样", 19, p);
49 Student s2 = (Student) s1.clone();
50 System.out.println(s1);//
51 System.out.println(s2);
52 System.out.println(s1==s2);
53
54 s2.p.name = "zhaoliu";
55 s2.p.age = 60;
56 System.out.println(s2);//
57 System.out.println(s1);
58 }
59 }
总结:
- 如果自定义类型包含引用类型的数据成员,必须考虑Clone方法是实现浅拷贝(shallow copy)还是深拷贝(deep copy)。
- 浅拷贝是指副本对象中的引用类型的数据成员与源对象的数据成员指向相同的对象。而如果是深拷贝,则必须创建整个对象的结构,副本对象中的引用 类型的数据成员与源对象的数据成员指向不同的对象。
- 当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
- 当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
PS:
如果,您希望更容易地发现我的新博客,不妨点击一下关注。
如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【肥肥也】!
Java 的序列化 (Serializable)(Day_09)的更多相关文章
- Java基础--序列化Serializable
对Java对象序列化的目的是持久化对象或者为RMI(远程方法调用)传递参数和返回值. 下面是一个序列化对象写入文件的例子: ---------------------------- package u ...
- Java 的序列化Serializable接口介绍及应用
常看到类中有一串很长的 如 private static final long serialVersionUID = -4667619549931154146L;的数字声明.这些其实是对此类进行序列化 ...
- JAVA 对象序列化——Serializable
1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存object st ...
- JAVA 对象序列化——Serializable(转)
文章出自:http://www.cnblogs.com/chenfei0801/archive/2013/04/05/3001149.html Java的对象序列化是指将那些实现了Serializab ...
- Java 序列化Serializable详解
Java 序列化Serializable详解(附详细例子) Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连 ...
- Java 序列化Serializable接口
1 什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程. 2 什么情况下需要 ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...
- JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
JAVA之旅(三十)--打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 三十篇了,又是一个 ...
- Java序列化Serializable和Externalizable
纸上得来终觉浅,绝知此事要躬行 --陆游 问渠那得清如许,为有源头活水来 --朱熹 什么是Java序列化?为什么出现Java序列化?怎样实现Java序列化? 一.什么是Java序列化 ...
随机推荐
- redis的持久化有哪几种方式?不同的持久化机制都有什么优缺点?(偏难)
1.RDB和AOF两种持久化机制的介绍 RDB持久化机制,对redis中的数据执行周期性的持久化 AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的 ...
- Seata搭建与分布式事务入门
在单体架构下,我们大多使用的是单体数据库,通过数据库的ACID特性支持,实现了本地事务.但是在微服务架构下复杂的业务关系中,分布式事务是不可避免的问题之一.Seata是Spring Cloud Ali ...
- ECDSA密钥对生成以及在Token中的应用
1 概述 本文主要讲述了如何利用Openssl生成ECDSA密钥对,并利用Auth0库进行Token生成及验证的过程. 2 ECDSA 2.1 简介 ECC(Elliptic Curve Crypto ...
- kubernetes node SchedulingDisabled
问题: k8s 集群的节点处于 SchedulingDisabled 解决方案 kubectl patch node NodeName -p "{\"spec\":{\& ...
- redhat 7.6 部署禅道 yum [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.
记个流水账 redhat 7.6 上部署 禅道. 禅道官网下载 http://dl.cnezsoft.com/zentao/9.8.3/ZenTaoPMS.9.8.3.zbox_64.tar.gz ...
- C语言-内存函数的实现(二)之memmove
C语言中的内存函数有如下这些 memcpy memmove memcmp memset 下面看看memmove函数 memmove 为什么会需要memmove函数? int main() { int ...
- goloader - golang动态加载的实现
github地址:https://github.com/dearplain/goloader 这里有以前的一些思路:http://www.cnblogs.com/dearplain/p/8145985 ...
- 16- web测试总结
在线用户不进行任何操作,对服务器也会产生压力.因为有会话的存在. 服务器tps与相应时间没有直接关系:每个口 关键性能指标:TPS.响应时间.并发数.思考时间.资源利用率(内存.cpu.磁盘).pv. ...
- img 的data-src 属性及懒加载
一.什么是图片懒加载 当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),当图片出现在浏览器的可视区域内时,才设置图片真正的路径, ...
- hdu4291 暴力循环节+矩阵快速幂
题意: 给你一个关系式,x[n] = 3*x[n-1] + x[n-2],求x(x(x[n]))%1000000007. 思路: 做这个题目要明确一点,就是对于取余操作大多数时 ...