栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

代码分析(十)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

代码分析(十)

2021SC@SDUSC

在我们进行apijson的分析时,出现了很多的“parser”类,这些类的大致作用就是去将一些对象去进行序列化,或者解析其序列化,而序列化与反序列化又具体是什么呢?我们这次便分析一下序列化与反序列化,以及与此项目的一些关系,和具体的使用

基本概念

(1)序列化和反序列化的定义:

    Java序列化就是指把Java对象转换为字节序列的过程

    Java反序列化就是指把字节序列恢复为Java对象的过程。

(2)序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。

   反序列化的最重要的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。

核心作用就是对象状态的保存和重建。

举个例子:
现在我们都会在网上买桌子,桌子这种很不规则不东西,是怎么从一个城市运输到另一个城市的?我们一般都会把它拆掉成一个一个的板子,再装到箱子里面,就可以快递寄出去了,这个过程就类似我们的序列化的过程(把数据转化为可以存储或者传输的形式)。当买家收到时,就需要自己把这些板子组装成桌子的样子,这个过程就像反序列 的过程(转化成当初的数据对象)。

那是怎么进行序列化的呢?

Java实现序列化和反序列化的过程

1、实现序列化的必备要求:

   只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列。(不是则会抛出异常) 

2、JDK中序列化和反序列化的API:

  ①java.io.ObjectInputStream:对象输入流。

      该类的readObject()方法从输入流中读取字节序列,然后将字节序列反序列化为一个对象并返回。

 ②java.io.ObjectOutputStream:对象输出流。

      该类的writeObject(Object obj)方法将将传入的obj对象进行序列化,把得到的字节序列写入到目标输出流中进行输出。

3、实现序列化和反序列化的三种实现:

①若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化。

         ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。 
         ObjcetInputStream采用默认的反序列化方式,对Student对象的非transient的实例变量进行反序列化。

②若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

       ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。 
       ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

③若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

       ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。 
       ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

序列化和反序列化的注意点:

①序列化时,只对对象的状态进行保存,而不管对象的方法;

②当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

③当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

④对象序列化的安全性问题,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行RMI传输等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的;

⑤声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据。

⑥序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为它赋予明确的值。显式地定义serialVersionUID有两种用途:

⑦Java有很多基础类已经实现了serializable接口,比如String,Vector等。

⑧如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存!这是能用序列化解决深拷贝的重要原因;

测试

我们来看一下在我们的apijson里面是如何使用的,我们直接简化一个例子

public class Student implements Serializable{                             
                                                                          
    private static final long serialVersionUID = -6060343040263809614L;   
                                                                          
    private String userName;                                              
    private String password;                                                                                               
                                                                          
    public String getUserName() {                                         
        return userName;                                                  
    }                                                                     
                                                                          
    public String getPassword() {                                         
        return password;                                                  
    }                                                                     
                                                                          
    public void setUserName(String userName) {                            
        this.userName = userName;                                         
    }                                                                     
                                                                          
    public void setPassword(String password) {                            
        this.password = password;                                         
    }                                                                     
                                                                                                                                                                                               
    public Student(String userName, String password) {       
        this.userName = userName;                                         
        this.password = password;                                                                                   
    }                                                                     
}                                                                         
public class SerializableTest {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            //序列化
            FileOutputStream fos = new FileOutputStream("object.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            Student student1 = new Student("张三", "123456");
            oos.writeObject(student1);
            oos.flush();
            oos.close();
            //反序列化
            FileInputStream fis = new FileInputStream("object.out");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student student2 = (Student) ois.readObject();
            System.out.println("Name is: "+student2.getUserName());
            System.out.println("Password is: "+student2.getPassword());
    }
 
}

这里面student类去实现了序列化,那么我们经过测试得到的结果就是

Name is:张三
Password is:123456

这也就是我们的apijso里面使用序列化时的概念

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/658339.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号