源码分析前的知识Serializable

一、源码分析前的知识补充

1、Serializable标记型接口

(1)介绍

类的序列化由实现java.io.Serializable接口的类启用,不实现此接口的类将不会使任何状态序列化或反序列化。可序列化的所有子类型都是可序列化的。

序列化:将对象的数据写入到文件

反序列化:将对象中的数据读取出来。

(2)代码演示

package com.集合.ArrayList;

import java.io.*;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

public class Demo {

    /*

    * 4个用户对象,要求将4个人用户对象序列化到当前目录下的stu.txt中

    * 序列化成功后,通过反序列化将数据读取出来,打印到控制台

    * */

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        User user1 = new User("张三", 29);

        User user2 = new User("李四", 10);

        User user3 = new User("王五", 20);

        User user4 = new User("赵六", 19);

        ArrayList<User> users = new ArrayList<>();

        Collections.addAll(users,user1,user2,user3,user4);

        //创建对象操作流

        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("stu.txt"));

        outputStream.writeObject(users);

        outputStream.close();

        ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("stu.txt"));

        ArrayList<User> list = (ArrayList<User>) inputStream.readObject();

        for (User user : list) {

            System.out.println(user);

        }

    }

}

class User implements Serializable {

    private String name;

    private int age;

    public User(String name, int age) {

        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(int age) {

        this.age = age;

    }

    /*

    *字符串在拼接时,会产生大量的对象,非常占内存,所以对toString进行优化

    *用StringBuilder进行优化 它在创建的过程中只一个对象

    **/

    @Override

    public String toString() {

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("User【name='").append(this.name).append("',age=").append(this.age).append("】");

        return stringBuilder.toString();

       /* return "User{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';*/

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

2、Cloneable标记型接口

(1)介绍

一个类实现Cloneable接口来指示Object.clone()方法,该方法对于该类的实例进行字段的复制是合法的。不实现Cloneable接口的实例上调用对象的克隆方法会导致异常。

(2)克隆的前提条件

被克隆对象所在的类必须实现Cloneable接口

必须重写clone方法

(3)浅克隆

浅克隆:复制对象时仅仅复制对象本身,包括基本属性,但该对象的属性引用其他对象时,该引用对象不会被复制,即拷贝出来的对象与被拷贝出来的对象中的属性引用的对象是同一个。

package com.集合.ArrayList;

public class Demo2 {

    public static void main(String[] args) throws CloneNotSupportedException {

        Teacher teacher = new Teacher("张三的老师");

        Student student1 = new Student("张三", 23,teacher);

        Object student2 = student1.clone();

        System.out.println(student1 == student2);

        //浅克隆 更改student1的内容,student2不会受到影响

        teacher.setName("李四的老师");

        System.out.println(student1);

        System.out.println(student2);

    }

}

class Student implements Cloneable{

    private String name;

    private int age;

    private Teacher teacher;

    public Student(String name, int age, Teacher teacher) {

        this.name = name;

        this.age = age;

        this.teacher = teacher;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public Teacher getTeacher() {

        return teacher;

    }

    public void setTeacher(Teacher teacher) {

        this.teacher = teacher;

    }

    @Override

    protected Object clone() throws CloneNotSupportedException {

        //调用Object类的本地方法

        return super.clone();

    }

    @Override

    public String toString() {

        return "Student{" +

                "name='" + name + '\'' +

                ", age=" + age +

                ", teacher=" + teacher +

                '}';

    }

}

class Teacher{

    private String name;

    public Teacher(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    @Override

    public String toString() {

        return "Teacher{" +

                "name='" + name + '\'' +

                '}';

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

输出是

false

Student{name='张三', age=23, teacher=Teacher{name='李四的老师'}}

Student{name='张三', age=23, teacher=Teacher{name='李四的老师'}}

我们发现修改原来的值,拷贝后的值也发生了修改。

1

2

3

4

(4)深克隆

深克隆:**复制对象本身的同时,也复制对象包含的引用指向的对象,**即修改被克隆对象的任何属性都不会影响到克隆出来的对象。

猜你喜欢

转载自www.cnblogs.com/ibdibd/p/12940968.html