• java对象序列化


    定义:

      对象序列化目标是将对象保存在磁盘中,允许在网络中直接传输对象。序列化机制把内存中的java对象转化成与平台无关的二进制流,从而可以把这种二进制

    流永久的保存在磁盘上,通过网络把二进制流传送到另一个网络节点,其他程序一旦获得了二进制流,不管是从磁盘还是网络获取的,都可以将此转换成java对象。

    如果要把某个对象序列化,这个对象必须要实现Serializable接口,实现此接口无需实现任何方法,此接口只是告诉java此对象是可以被序列化的。

    此接口是一个标记接口。  

    被序列化的User对象,

    import java.io.Serializable;
    
    public class User implements Serializable{
        private String name;
        private int 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;
        }
    }

    将User对象序列化,创建一个输出流输出到磁盘

    public static void main(String[] args) throws Exception{
            FileOutputStream fos = new FileOutputStream("d:/object.txt");
            ObjectOutputStream oos =new ObjectOutputStream(fos);
            
            User u =new User();
            u.setName("jack");
            u.setAge(43);
            
            oos.writeObject(u);
        }

    反序列化,创建一个输入流,从磁盘读取

    public static void main(String[] args) throws Exception{
            FileInputStream fis = new FileInputStream("d:/object.txt");
            ObjectInputStream ois =new ObjectInputStream(fis);
            
            User u =(User)ois.readObject();
            //输出 jack    43
            System.out.println(u.getName() +"	"+u.getAge());
        }

    由此,序列化还是很容易理解的

    还有几点说明:

      1.反序列化不是通过构造器来初始化java对象的,可以用构造方法来验证。

      2.如果序列化向文件中写入了多个对象,反序列化必须按照实际写入的顺序读取。

      3.如果被序列化对象的直接或间接父类是不可序列化的,只带有无参数构造器,改父类定义的成员不会被序列化。

        4.被序列化的引用类也必须实现Serializable接口; 

    对象引用序列化:

      序列化对象Person 有一个User对象的引用:

    import java.io.Serializable;
    
    public class Person implements Serializable{
        private String id ;
        private User u;
        
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public User getU() {
            return u;
        }
        public void setU(User u) {
            this.u = u;
        }
    }

      如果某对象被其他多个不同对象引用,需要序列化,java不会对同意对象做多次序列化,因此java序列有特殊算法(序列化底层机制):

      *所有保存到磁盘的序列化对象都有一个编号。

      *当程序试图序列化对象时,java会先检查此对象在本次虚拟机中是否被序列化过。

      *如果被序列化过,则输出上次序列化的编号,而不是重新序列化改对象。

    那么,做个重复序列化测试

        public static void main(String[] args)  {
            try{
                FileOutputStream fos = new FileOutputStream("d:/object.txt");
                ObjectOutputStream oos =new ObjectOutputStream(fos);
                
                FileInputStream fis = new FileInputStream("d:/object.txt");
                ObjectInputStream ois =new ObjectInputStream(fis);
                
                User u =new User();
                u.setName("第一次序列化");
                oos.writeObject(u);
                u.setName("第二次序列化");
                oos.writeObject(u);
                //读取流
                ois.readObject();
                User ui =(User)ois.readObject();
                //发现输出 : 第一次序列化
                System.out.println(ui.getName() );
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    发现结果符合它的机制的确没有做二次序列化,即使对象的属性被修改

     

  • 相关阅读:
    蛋疼的springboot web项目使用jetty容器运行
    freemark 异常
    系统中个别页面间断性跳转到登录页异常
    Spring Transaction 使用入门
    单例模式
    抽象工厂模式
    工厂模式
    设计模式
    关于ZK框架的onScroll事件的问题
    关于CheckStyle在eclipse出现的问题
  • 原文地址:https://www.cnblogs.com/Marvellous/p/4063648.html
Copyright © 2020-2023  润新知