Welcome everyone

序列化核心用法

java 汪明鑫 781浏览 0评论

概念

序列化:对象->字节
反序列化:字节->对象

Demo

核心接口:Serializable
核心类:ObjectInputStreamObjectOutputStream
核心方法:writeObjectreadObject
注意点serialVersionUID
public class Person implements Serializable {
 
    private static final long serialVersionUID = -7290089721196747652L;
 
    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;
    }
 
   
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age 
        
                '}';
    }
}

 

public class SerializeDemo {
    public static void main(String [] args){
 
        //序列化操作
        SerializePerson();
 
        //反序列化操作
        DeSerializePerson();
 
    }
 
 
    public static void SerializePerson(){
        try {
            ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));
            Person person=new Person();
            person.setName("c罗");
            person.setAge(32);
            oo.writeObject(person);
            oo.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static void DeSerializePerson(){
        try {
            ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
            Person person = (Person)oi.readObject();
            System.out.println(person);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 

序列化时类指定UID,反序列化时类没有指定UID(系统会给你自动指定一个UID)
两个UID不一致,会报错
serialVersionUID可以保证序列化和反序列化对象一致

静态变量不能被序列化

在刚才的Person对象中增加一个静态变量字段height
public static int height = 178;
public static void main(String [] args){
 
    //序列化操作
    SerializePerson();
 
    Person.height=180;
 
    //反序列化操作
    Person person=DeSerializePerson();
    System.out.println(person.height);
 
}

结果打印的不是序列化对象的height=178,而是我们设置的180

也就是说,静态变量不能被序列化

transient变量不能被序列化

在Person类中加一个变量transient修饰的sex

private transient String sex;

public class SerializeDemo3 {
    public static void main(String [] args){
 
        //序列化操作
        SerializePerson();
 
        //反序列化操作
        Person person=DeSerializePerson();
        System.out.println(person);
 
    }
 
 
    public static void SerializePerson(){
        try {
            ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));  //默认在根目录
            Person person=new Person();
            person.setName("c罗");
            person.setAge(32);
            person.setSex("man");
            oo.writeObject(person);
            oo.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static Person DeSerializePerson(){
        try {
            ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
            Person person = (Person)oi.readObject();
            return person;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

sex打印为空,说明transient关键字指定的属性不参与序列化

 

父子类的序列化

如果父类没有实现序列化,而子类实现列序列化。那么父类中的成员没办法做序列化操作

 

public class SuperUser {
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    public String toString() {
        return "SuperUser{" +
                "name='" + name + '\'' +
                '}';
    }
}
 
public class User extends SuperUser implements Serializable {
    private static final long serialVersionUID = -1290089721196747652L;
 
    @Override
    public String toString() {
        return "User{} " + super.toString();
    }
}
 
public class MyTest {
    public static void main(String [] args){
 
        //序列化操作
        SerializeUser();
 
        //反序列化操作
        User user=DeSerializeUser();
        System.out.println(user);
 
    }
 
 
    public static void SerializeUser(){
        try {
            ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("user")));  //默认在根目录
            User user=new User();
            user.setName("c罗");
 
            oo.writeObject(user);
            oo.close();
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static User DeSerializeUser(){
        try {
            ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("user")));
            User user = (User)oi.readObject();
            return user;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
 
}

name打印为null

说明父类属性没有参与序列化,因为父类没有实现Serializable接口

把父类也实现Serializable就可以了

 

序列化的存储规则

public class SerializeDemo4 {
    public static void main(String [] args){
 
        //序列化操作
        SerializePerson();
 
        //反序列化操作
        Person person=DeSerializePerson();
        System.out.println(person);
 
    }
 
 
    public static void SerializePerson(){
        try {
            ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));  //默认在根目录
            ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
            Person person=new Person();
            person.setName("c罗");
            person.setAge(32);
            person.setSex("man");
            oo.writeObject(person);
            oo.flush();
            System.out.println("第一次序列化成功,长度为"+new File("person").length());
            Person person1=(Person)oi.readObject();
            oo.writeObject(person);
            oo.flush();
            System.out.println("第二次序列化成功,长度为"+new File("person").length());
            Person person2=(Person)oi.readObject();
            oo.close();
 
 
 
 
            System.out.println(person1==person2);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static Person DeSerializePerson(){
        try {
            ObjectInputStream oi=new ObjectInputStream(new FileInputStream(new File("person")));
            Person person = (Person)oi.readObject();
            return person;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

 

 

序列化实现深度克隆

public class Student implements Serializable {
 
    private static final long serialVersionUID = -3330089721196747652L;
 
    private String name;
    private int age;
 
    private 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;
    }
 
    //序列化的方式实现深度克隆
    public Object deepClone() throws  Exception{
 
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(this);
 
        ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois=new ObjectInputStream(bis);
 
        return ois.readObject();
 
    }
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", teacher=" + teacher +
                '}';
    }
}
public class Teacher implements Serializable {
 
    private static final long serialVersionUID = -4330089021196747652L;
 
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class cloneDemo {
    public static void main(String []args)throws  Exception{
        Teacher teacher = new Teacher();
        teacher.setName("a");
 
        Student student=new Student();
        student.setName("zhangsan");
        student.setAge(18);
        student.setTeacher(teacher);
 
        System.out.println(student);
 
        Student s = (Student)student.deepClone();
        System.out.println(s);
 
        System.out.println("student==s : "+(student==s));   //返回false表示不是指向同一个对象,即深度克隆
        System.out.println("student.equals(s) : "+(student.equals(s)));
 
        //修改s的老师的引用对象的属性值
        s.getTeacher().setName("b");
        System.out.println(student);
        System.out.println(s);
 
    }
 
 
}

 

 

主流的序列化技术

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>pers.wmx.demo</groupId>
    <artifactId>Serialize</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <dependencies>
 
        <!-- spring默认的-->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
 
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>
 
        <!--  百度封装的 -->
        <dependency>
            <groupId>com.baidu</groupId>
            <artifactId>jprotobuf</artifactId>
            <version>2.1.2</version>
        </dependency>
 
        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.38</version>
        </dependency>
 
    </dependencies>
 
</project>

 

public class JsonDemo {
 
    private static Person init(){
        Person person = new Person();
        person.setName("梅西");
        person.setAge(30);
        return person;
 
    }
 
    public static void main(String []args)throws Exception{
 
        System.out.println("JackSon序列化...");
        excuteWithJack();
 
        System.out.println("FastJson序列化...");
        excuteWithFastJson();
 
        System.out.println("Protobuf序列化...");
        excuteWithProtobuf();
 
        System.out.println("Hessian序列化...");
        excuteWithHessian();
 
    }
 
    //使用jackson序列化
    private static void excuteWithJack() throws Exception{
        Person person=init();
 
        ObjectMapper mapper = new ObjectMapper();
 
        byte [] writeBytes=null;
 
        Long start=System.currentTimeMillis();
        for(int i=0;i<10000;i++){
            writeBytes=mapper.writeValueAsBytes(person);
        }
 
        System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
        System.out.println(writeBytes.length);
 
        Person person1 = mapper.readValue(writeBytes,Person.class);
        System.out.println(person1);
    }
 
 
    //使用fastjson序列化
    private static void excuteWithFastJson() throws Exception{
        Person person=init();
        String text=null;
 
 
        Long start=System.currentTimeMillis();
        for(int i=0;i<10000;i++){
            text=JSON.toJSONString(person);
        }
 
        System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
        System.out.println("text "+text);
        System.out.println(text.getBytes().length);
 
        Person person1 = JSON.parseObject(text,Person.class);
        System.out.println("person1 "+person1);
 
    }
 
    //使用Protobuf序列化     性能高    字节数小,适合网络传输
    private static void excuteWithProtobuf() throws Exception{
        Person person=init();
 
        Codec<Person> personCodec =ProtobufProxy.create(Person.class,false);
 
        Long start=System.currentTimeMillis();
        byte[] bytes=null;
        for (int i = 0; i <10000 ; i++) {
            bytes=personCodec.encode(person);
        }
 
        System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
        System.out.println(bytes.length);
 
        Person person1 = personCodec.decode(bytes);
        System.out.println(person1);
    }
 
 
    //使用Hessian序列化
    private static void excuteWithHessian() throws Exception{
        Person person=init();
 
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        HessianOutput ho=new HessianOutput(baos);
 
        Long start=System.currentTimeMillis();
 
        for (int i = 0; i <10000 ; i++) {
            ho.writeObject(person);
        }
 
        System.out.println("序列化用时"+(System.currentTimeMillis()-start)+"ms");
        System.out.println(baos.toByteArray().length);
 
        ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
        HessianInput hi=new HessianInput(bais);
        Person person1 = (Person)hi.readObject();
        System.out.println(person1);
    }
}

 

本篇文章是复习序列化然后从我的CSDN迁过来的,哈哈…

转载请注明:汪明鑫的个人博客 » 序列化核心用法

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz