美文网首页
java序列化

java序列化

作者: 冷月成双 | 来源:发表于2019-11-14 23:17 被阅读0次

java序列化机制 Serialize 接口
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

java序列化得主要目的 :

  • 网络传输
  • 对象持久化

java序列化对象代码 :

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = 1L;
    
    private String name;
    private int id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }   
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerilizedDemo {

    public static void main(String[] args) {
        deSerializeMethod();
    }
    /**
     * 序列化方法
     */
    private static void serializeMethod() {
        try {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("Person")));
            Person person = new Person();
            person.setId(1);
            person.setName("wang");
            out.writeObject(person);
            out.close();
            System.out.println("序列化成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 反序列化方法
     */
    private static void deSerializeMethod() {
        try {
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("Person")));
            Person person = (Person)inputStream.readObject();
            System.out.println("反序列化成功 : "+person);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行main方法结果为 :

序列化成功
反序列化成功 : Person [name=wang, id=1]
  • 静态变量的序列化

序列化不保存静态变量的状态.

import java.io.Serializable;

public class Person implements Serializable {

    private static final long serialVersionUID = 1L;
    //静态变量
    public static int age = 20;
    private String name;
    private int id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }   
}   

序列化方法还是用上面的代码,反序列化将静态变量的值作修改:

    /**
     * 反序列化方法
     */
    private static void deSerializeMethod() {
        try {
            //这里重新设置静态变量的值
            Person.age = 10;
            ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("Person")));
            Person person = (Person)inputStream.readObject();
            System.out.println("反序列化成功 : "+person);
            System.out.println(person.age);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

再次运行main方法,结果为:

序列化成功
反序列化成功 : Person [name=wang, id=1]
10 //发现这里的值是修改后的值
  • transient关键字

    transient关键字修饰的变量不被序列化,还是刚才的Person类,我们在name属性上加上这个属性看看结果:

    import java.io.Serializable;
    
    public class Person implements Serializable {
    
      private static final long serialVersionUID = 1L;
        //静态变量
      public static int age = 20;
        //注意这里加了 transient 关键字
      private transient String name;
      private int id;
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public int getId() {
          return id;
      }
      public void setId(int id) {
          this.id = id;
      }
      @Override
      public String toString() {
          return "Person [name=" + name + ", id=" + id + "]";
      }   
    }
    

    还是刚才的main方法再次执行结果为:

    序列化成功
    反序列化成功 : Person [name=null, id=1] //这里name没有值了,表明没有被序列化,所以反序列化时没有值
    10
    
  • 父子类序列化问题

    父类如果要序列化也要实现 Serializable接口.

    看下面的示例:

    //Human没有序列化
    public class Human {
      public int height;
      public int getHeight() {
          return height;
      }
      public void setHeight(int height) {
          this.height = height;
      }
    }
    
    public class Person extends Human implements Serializable,Cloneable {
        private static final long serialVersionUID = 1L;
      public static int age = 20;
      private String name;
      private int id;
      
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public int getId() {
          return id;
      }
      public void setId(int id) {
          this.id = id;
      }
      @Override
      public String toString() {
          return "Person [name=" + name + ", id=" + id + ", height=" + height + "]";
      }
    }
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    public class SerilizedDemo {
    
      public static void main(String[] args) {
          serializeMethod();
          deSerializeMethod();
      }
      /**
       * 序列化方法
       */
      private static void serializeMethod() {
          try {
              ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("Person")));
              Person person = new Person();
              person.setId(1);
              person.setName("wang");
                //这里设置了值
              person.setHeight(170);
              out.writeObject(person);
              out.flush();
              out.close();
              System.out.println("序列化成功");
          } catch (IOException e) {
              e.printStackTrace();
          } 
      }
      /**
       * 反序列化方法
       */
      private static void deSerializeMethod() {
          try {
              ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("Person")));
              Person person = (Person)inputStream.readObject();
              System.out.println("反序列化成功 : "+person);
          } catch (IOException e) {
              e.printStackTrace();
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          }
      }
    }
    

    运行main方法,结果为 :

    序列化成功
    反序列化成功 : Person [name=wang, id=1, height=0]//这里height为0,不是我们设置的值,说明没有序列化
    

    现在我们将Human类实现序列化:

    import java.io.Serializable;
    //实现序列化   
    public class Human implements Serializable{
    
      private static final long serialVersionUID = -1149910849791261774L;
      public int height;
    
      public int getHeight() {
          return height;
      }
    
      public void setHeight(int height) {
          this.height = height;
      }
    }
    

    再次运行main方法结果为:

    序列化成功
    反序列化成功 : Person [name=wang, id=1, height=170]//发现设置的值生效了
    
  • 序列化实现深克隆

浅拷贝 : 不复制引用

深拷贝 : 复制引用

public class Test {
  public static void main(String[] args) {
      deepCloneTest();
  }
  private static void deepCloneTest() {
      Person person = new Person();
      Teacher teacher = new Teacher();
      teacher.setName("wang");
      person.setId(1);
      person.setName("peng");
      person.setTeacher(teacher);
      try {
            //浅拷贝
          Person person1 =  (Person) person.clone(); 
            //当这里修改值时会把 person1 里面的teacher的值也修改,所以下面的结果为
           // person : Person [name=peng, id=1, teacher=Teacher [name=ming]]
//person1 : Person [name=peng, id=1, teacher=Teacher [name=ming]]
//person2 : Person [name=peng, id=1, teacher=Teacher [name=ming]]
           // teacher.setName("ming");
            //深拷贝 
          Person person2 = person.deepClone();
            //这里只会改前面的结果不会改变person2里面teacher的值
            //person : Person [name=peng, id=1, teacher=Teacher [name=ming]]
//person1 : Person [name=peng, id=1, teacher=Teacher [name=ming]]
//person2 : Person [name=peng, id=1, teacher=Teacher [name=wang]]
          teacher.setName("ming");
          System.out.println("person : "+person.toString());
          System.out.println("person1 : "+person1.toString());
          System.out.println("person2 : "+person2.toString());
      } catch (ClassNotFoundException | IOException | CloneNotSupportedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  }
}

public class Person implements Serializable,Cloneable {

    private static final long serialVersionUID = 1L;
  public static int age = 20;
  private String name;
  private int id;
  private Teacher teacher;
  
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public int getId() {
      return id;
  }
  public void setId(int id) {
      this.id = id;
  }
  
  public Teacher getTeacher() {
      return teacher;
  }
  public void setTeacher(Teacher teacher) {
      this.teacher = teacher;
  }
  /**
   * 深克隆方法
   * @return
   * @throws ClassNotFoundException
   * @throws IOException
   */
  public Person deepClone() throws ClassNotFoundException, IOException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream os = new ObjectOutputStream(bos);
      os.writeObject(this);
      ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
      ObjectInputStream is = new ObjectInputStream(bis);
      Person student = (Person)is.readObject();
      return student;
  }
  /**
   * 浅拷贝
   */
  @Override
  protected Object clone() throws CloneNotSupportedException {
      return super.clone();
  }
  @Override
  public String toString() {
      return "Person [name=" + name + ", id=" + id + ", teacher=" + teacher.toString() + "]";
  }   
}
public class Teacher implements Serializable,Cloneable {
  private static final long serialVersionUID = -3273424656529143724L;
  private String name;
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  @Override
  public String toString() {
      return "Teacher [name=" + name + "]";
  }
}

java序列化得缺点 :

  1. 无法跨语言
  2. 序列化之后的码流太大
  3. 序列化性能低

相关文章

  • Java-序列化-反序列化

    Thanks Java基础学习总结——Java对象的序列化和反序列化java序列化反序列化原理Java 序列化的高...

  • java序列化那些事儿

    java序列化作用 在说java序列化的作用之前,先说下什么是java序列化吧。java序列化是指把java对象转...

  • Java序列化

    Java序列化的几种方式以及序列化的作用 Java基础学习总结——Java对象的序列化和反序列化

  • Java序列化机制

    Java序列化机制 序列化和反序列化 Java序列化是Java内建的数据(对象)持久化机制,通过序列化可以将运行时...

  • Java 序列化 之 单例模式

    序列化相关文章: Java 序列化 之 Serializable Java 序列化之 Externalizable...

  • java 序列化 原理解析

    序列化相关文章: Java 序列化 之 Serializable Java 序列化之 Externalizable...

  • 认识Java序列化

    我的个人博客,认识Java序列化 引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java ...

  • JDK 序列化

    序列化和分序列化概念 什么是序列化和反序列化 Java序列化是指把Java对象转换为字节序列的过程,而Java反序...

  • Spark序列化

    Java序列化 有关Java对象的序列化和反序列化也算是Java基础的一部分,首先对Java序列化的机制和原理进行...

  • Serializable中为什么要设置UID

    1、什么是Java序列化与反序列化 Java序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指...

网友评论

      本文标题:java序列化

      本文链接:https://www.haomeiwen.com/subject/hzwdictx.html