美文网首页
序列化(java Serializeable、json、prot

序列化(java Serializeable、json、prot

作者: 凉风拂面秋挽月 | 来源:发表于2020-03-28 14:21 被阅读0次

java序列化

序列化:将对象写入到IO流中
反序列化:从IO流中恢复对象
意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。
实例(Person实现了Serializeable接口):

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
          //将对象序列化到文件object.txt
          Person person = new Person("xuxiao", 222);
          oos.writeObject(person);

反序列化

 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
          Person person = (Person) ois.readObject();
          System.out.println(person);

ps:反序列化生成对象不会调用构造方法。反序列的对象是由JVM自己生成的对象,不通过构造方法生成。

transient关键字

有些时候,我们有这样的需求,某些属性不需要序列化。使用transient关键字选择不需要序列化的字段。

public class Person implements Serializable {
   //不需要序列化名字与年龄
   private transient String name;
   private transient int age;
   private int height;
   private transient boolean singlehood;
   public Person(String name, int age) {
       this.name = name;
       this.age = age;
   }
   //省略get,set方法
}
public class TransientTest {
   public static void main(String[] args) throws Exception {
       try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.txt"));
            ObjectInputStream ios = new ObjectInputStream(new FileInputStream("person.txt"))) {
           Person person = new Person("xuxiao", 222);
           person.setHeight(180);
           System.out.println(person);
           oos.writeObject(person);
           Person p1 = (Person)ios.readObject();
           System.out.println(p1);
       }
   }
}

输出结果:

//Person{name='xuxiao', age=222', singlehood=true', height=180cm}
//Person{name='null', age=0', singlehood=false', height=180cm}

使用transient修饰的属性,java序列化时,会忽略掉此字段,所以反序列化出的对象,被transient修饰的属性是默认值。对于引用类型,值是null;基本类型,值是0;boolean类型,值是false。

json

json是一种轻量级的数据交换格式。它基于 [ECMAScript] (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。360百科

JSON建构于两种结构:
“键/值”对的集合(A collection of name/value pairs)
在不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。 (结构)
而它的值,是有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。 (值=数组)

java中经常使用json格式来与前端交互,我通常使用fastjson来将javabean与json字符串之间相互转换。

Person person = new Person(20, "John", "Doe", new Date());
String jsonObject = JSON.toJSONString(person);
Person newPerson = JSON.parseObject(jsonObject, Person.class);

Json和Java实体的数据类型的对照(映射):

image.png

protobuf

protobuf是google团队开发的用于高效存储和读取结构化数据的工具。什么是结构化数据呢,正如字面上表达的,就是带有一定结构的数据。比如电话簿上有很多记录数据,每条记录包含姓名、ID、邮件、电话等,这种结构重复出现。
xml、json也可以用来存储此类结构化数据,但是使用protobuf表示的数据能更加高效,并且将数据压缩得更小,大约是json格式的1/10,xml格式的1/20。

实际使用:
1.到http://code.google.com/p/protobuf/downloads/list ,选择其中的win版本下载,我选择的是protoc-2.4.1-win32.zip

2.下载一个protobuf-java-2.4.1.jar文件(注意,要与你刚才下的proto.exe版本相同)
3.用记事本编写一个.proto文件:
}如:我编写的是test.proto

package protobuf;
option java_package = "com.sq.protobuf";
option java_outer_classname = "FirstProtobuf";
message testBuf {
required int32 ID = 1;
required string Url = 2;
}
将其放在与刚解压的protoc.exe同级目录中。

在cmd中,到protoc-2.4.1-win32文件夹下,
执行
E:\protoc-2.4.1-win32> protoc.exe --java_out=./ test.proto
则可以找到的一个生成的FirstProtobuf.java文件。

5.将生成的FirstProtobuf.java放入工程。


image.png

6.编写测试类

package com.sq.protobuf;
import java.util.Arrays;
import com.google.protobuf.InvalidProtocolBufferException;

public class test2 {
    public static void main(String[] args) {
        //序列化   
    FirstProtobuf.testBuf.Builder builder = FirstProtobuf.testBuf.newBuilder(); 
        builder.setID(117);
        builder.setUrl("bangde");//同上
        // testBuf
        FirstProtobuf.testBuf info = builder.build();
        byte[] result = info.toByteArray();
        System.out.println("序列化结果:"+Arrays.toString(result));
        //反序列化过程
        try {
        
        FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(result);
        System.out.println("反序列化过程:"+"\n"+testBuf);//打印反序列化的值
        } catch (InvalidProtocolBufferException e) {
        e.printStackTrace();
        }
    }
}

运行结果:


image.png

java序列化,看这篇就够了
java中使用Protobuf的实例(Demo)

相关文章

网友评论

      本文标题:序列化(java Serializeable、json、prot

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