zoukankan      html  css  js  c++  java
  • 对象的序列化

    对象序列化就是把一个对象变为二进制数据流的一种方法。

    一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。

    先让我们实现一个具有序列化能力的类吧:

    【例子1】

    
    import java.io.*;  
    /**  
     * 实现具有序列化能力的类   
     */   
    
    public class SerializableDemo implements Serializable{
    
        public SerializableDemo(){
    
    
        }
    
        public SerializableDemo(String name, int age){
    
            this.name=name;
    
            this.age=age;
    
        }
    
        @Override
    
        public String toString(){
    
            return "姓名:"+name+"  年龄:"+age;
    
        }
    
        private String name;
    
        private int age;
    
    }
    

    这个类就具有实现序列化能力,在继续将序列化之前,先将一下ObjectInputStream和ObjectOutputStream这两个类

    先给一个ObjectOutputStream的例子吧:

    【例子2】

    
    import java.io.Serializable;   
    import java.io.File;    
    import java.io.FileOutputStream;      
    import java.io.IOException;     
    import java.io.ObjectOutputStream;    
    
    
    /**   
     * 实现具有序列化能力的类  
     */   
    
    public class Person implements Serializable{
    
        public Person(){
    
        }
    
    
    
        public Person(String name, int age){
    
            this.name = name;
    
            this.age = age;
    
        }
    
    
    
        @Override
    
        public String toString(){
    
            return "姓名:" + name + "  年龄:" + age;
    
        }
    
    
    
        private String name;
    
        private int age;
    
    }
    
    /**
    
     * 示范ObjectOutputStream
    
     * */
    
    public class ObjectOutputStreamDemo{
    
        public static void main(String[] args) throws IOException{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
    
                    file));
    
            oos.writeObject(new Person("rollen", 20));
    
            oos.close();
    
        }
    
    }
    

    【运行结果】:

    当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。

    虽然我们不能直接查看里面的内容,但是我们可以使用ObjectInputStream类查看:

    【例子3】

    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    
    /**  
     * ObjectInputStream示范   
     */   
    
    public class ObjectInputStreamDemo{
    
        public static void main(String[] args) throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectInputStream input = new ObjectInputStream(new FileInputStream(
    
                    file));
    
            Object obj = input.readObject();
    
            input.close();
    
            System.out.println(obj);
    
        }
    
    }
    

    【运行结果】:

    姓名:rollen 年龄:20

    到底序列化什么内容呢?

    其实只有属性会被序列化。

    • Externalizable接口

    被Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。

    当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。

    现在我们来演示一下序列化和反序列话:

    【例子4】

    
    package IO;
    
    import java.io.Externalizable;    
    import java.io.File;   
    import java.io.FileInputStream;   
    import java.io.FileOutputStream;   
    import java.io.IOException;   
    import java.io.ObjectInput;   
    import java.io.ObjectInputStream;   
    import java.io.ObjectOutput;   
    import java.io.ObjectOutputStream;  
    
    
    
    /**  
     * 序列化和反序列化的操作   
     */   
    
    public class ExternalizableDemo{
    
        public static void main(String[] args) throws Exception{
    
            ser(); // 序列化
    
            dser(); // 反序列话
    
        }
    
    
    
        public static void ser() throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
    
                    file));
    
            out.writeObject(new Person("rollen", 20));
    
            out.close();
    
        }
    
    
    
        public static void dser() throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectInputStream input = new ObjectInputStream(new FileInputStream(
    
                    file));
    
            Object obj = input.readObject();
    
            input.close();
    
            System.out.println(obj);
    
        }
    
    }
    
    
    
    class Person implements Externalizable{
    
        public Person(){
    
        }
    
    
    
        public Person(String name, int age){
    
            this.name = name;
    
            this.age = age;
    
        }
    
    
    
        @Override
        public String toString(){
    
            return "姓名:" + name + "  年龄:" + age;
    
        }
    
    
    
        // 复写这个方法,根据需要可以保存的属性或者具体内容,在序列化的时候使用
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException{
    
            out.writeObject(this.name);
    
            out.writeInt(age);
    
        }
    
    
    
        // 复写这个方法,根据需要读取内容 反序列话的时候需要
    
        @Override
        public void readExternal(ObjectInput in) throws IOException,
    
                ClassNotFoundException{
    
            this.name = (String) in.readObject();
    
            this.age = in.readInt();
    
        }
    
        private String name;
    
        private int age;
    
    }
    

    【运行结果】:

    姓名:rollen 年龄:20

    本例中,我们将全部的属性都保留了下来,

    Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,

    当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用transient关键字进行说明:

    下面举一个例子:

    【例子5】

    
    package IO;
    
    
    import java.io.File;  
    import java.io.FileInputStream;  
    import java.io.FileOutputStream;  
    import java.io.ObjectInputStream;  
    import java.io.ObjectOutputStream;  
    import java.io.Serializable;   
    
    /**  
     * 序列化和反序列化的操作   
     */   
    
    public class serDemo{
    
        public static void main(String[] args) throws Exception{
    
            ser(); // 序列化
    
            dser(); // 反序列话
    
        }
    
    
    
        public static void ser() throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
    
                    file));
    
            out.writeObject(new Person1("rollen", 20));
    
            out.close();
    
        }
    
    
    
        public static void dser() throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectInputStream input = new ObjectInputStream(new FileInputStream(
    
                    file));
    
            Object obj = input.readObject();
    
            input.close();
    
            System.out.println(obj);
    
        }
    
    }
    
    
    
    class Person1 implements Serializable{
    
        public Person1(){
    
    
        }
    
        public Person1(String name, int age){
    
            this.name = name;
    
            this.age = age;
    
        }
    
    
    
        @Override
        public String toString(){
    
            return "姓名:" + name + "  年龄:" + age;
    
        }
    
    
    
        // 注意这里
        private transient String name;
    
        private int age;
    
    }
    

    【运行结果】:

    姓名:null 年龄:20

    最后在给一个序列化一组对象的例子吧:

    【例子6】

    
    import java.io.File;   
    import java.io.FileInputStream;   
    import java.io.FileOutputStream;   
    import java.io.ObjectInputStream;   
    import java.io.ObjectOutputStream;   
    import java.io.Serializable;  
    
    
    /**  
     * 序列化一组对象  
     */  
    
    public class SerDemo1{
    
        public static void main(String[] args) throws Exception{
    
            Student[] stu = { new Student("hello", 20), new Student("world", 30),
    
                    new Student("rollen", 40) };
    
            ser(stu);
    
            Object[] obj = dser();
    
            for(int i = 0; i < obj.length; ++i){
    
                Student s = (Student) obj[i];
    
                System.out.println(s);
    
            }
    
        }
    
    
    
        // 序列化
        public static void ser(Object[] obj) throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
    
                    file));
    
            out.writeObject(obj);
    
            out.close();
    
        }
    
    
    
        // 反序列化
        public static Object[] dser() throws Exception{
    
            File file = new File("d:" + File.separator + "hello.txt");
    
            ObjectInputStream input = new ObjectInputStream(new FileInputStream(
    
                    file));
    
            Object[] obj = (Object[]) input.readObject();
    
            input.close();
    
            return obj;
    
        }
    
    }
    
    
    
    class Student implements Serializable{
    
        public Student(){
    
    
        }
    
        public Student(String name, int age){
    
            this.name = name;
    
            this.age = age;
    
        }
    
    
        @Override
        public String toString(){
    
            return "姓名:  " + name + "  年龄:" + age;
    
        }
    
    
        private String name;
    
        private int age;
    
    }
    

    【运行结果】:

    
    姓名:  hello  年龄:20
    
    姓名:  world  年龄:30
    
    姓名:  rollen  年龄:40
  • 相关阅读:
    硬件04:反馈与触发器
    硬件03:二进制减法器
    硬件02:二进制加法器
    ASP.NET MVC 表单提交多层子级实体集合数据到控制器中
    微信全局获取并缓存Accesstoken的值
    MySQL 中文显示乱码
    HTML5 Canvas绘图详解 drawImage() 方法 有图有真相!
    [原创]超强C#图片上传,加水印,自动生成缩略图源代码
    微信公共服务平台开发(.Net 的实现)5-------解决access_token过期的问题 .
    2015-10-19深圳面试
  • 原文地址:https://www.cnblogs.com/yuyu666/p/9733918.html
Copyright © 2011-2022 走看看