美文网首页
序列化:Serializable、Parcelable、JSON

序列化:Serializable、Parcelable、JSON

作者: 禄眠 | 来源:发表于2019-12-03 14:49 被阅读0次

大半个月没更新了,最近事情太多了,还有点懒。。。
不说了,继续更,正文开始

Serializable

Serializable是Java提供的序列化接口,使用方式也很简单,只要实现该接口就行了,实现了序列化后,我们就可以通过ObjectOutputStream把对象转成字节流,并且通过ObjectInputStream解析成对象

下文以Student类和Score类为例:

package com.example.serializationdemo;

import java.io.Serializable;

public class Student implements Serializable {

    private String name;
    private int age;
    private Score score;

    public Student(String name, int age, Score score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    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 Score getScore() {
        return score;
    }

    public void setScore(Score score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

class Score implements Serializable {

    private int math;
    private int english;

    public Score(int math, int english) {
        this.math = math;
        this.english = english;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getEnglish() {
        return english;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    @Override
    public String toString() {
        return "Score{" +
                "math=" + math +
                ", english=" + english +
                '}';
    }
}

然后我们对这个对象进行存储和解析

// 把对象转成字节流,存储为文件student.data
public void save(View view) {
    Student student = new Student("Tom", 20, new Score(60, 61));
    try {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(openFileOutput("student.data", MODE_PRIVATE));
        objectOutputStream.writeObject(student);
        objectOutputStream.flush();
        objectOutputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

// 从文件中读取并解析成对象
public void load(View view) {
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(openFileInput("student.data"));
        Student student = (Student) objectInputStream.readObject();
        textView.setText(student.toString());
        objectInputStream.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Parcelable

Parcelable是Android提供的序列化接口,使用相对于Serializable稍复杂些,但是在效率方面要快很多

下面以User类为例:

package com.example.serializationdemo;

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    protected User(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };

    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 "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

可以看到多了两个实现方法、一个构造方法和CREATOR变量

接着我们就可以在Activity之间传递了

Activity1:

public void useParcelable(View view) {

        User user = new User("Jack", 20);
        Intent intent = new Intent(this, ParcelableActivity.class);
        Bundle bundle = new Bundle();
        bundle.putParcelable("user", user);
        intent.putExtra("data", bundle);
        startActivity(intent);
    }

Activity2:

Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("data");
User user = bundle.getParcelable("user");
textView.setText(user.toString());

当然可以直接通过intent.putExtra("user", user);User user = intent.getParcelableExtra("user");实现,只不过放到Bundle中便于管理

JSON

JSON全称JavaScript Object Notation,一种轻量的文本数据格式,相比于xml数据格式,更加简洁,JSON中包括两种类型:对象和数组

这里使用Gson为例:

Gson是一个Java序列化/反序列化库,能够很方便的处理JSON格式字符串。Gson有两个常用方法:toJson()fromJson(),通过字面意思就很好理解

在使用之前,需要引入依赖:

implementation 'com.google.code.gson:gson:2.8.6'

下面我们以Phone类为例:

package com.example.serializationdemo;

public class Phone {

    private String name;
    private int price;

    public Phone(String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
Gson gson = new Gson();
Phone phone = new Phone("Android", 1000);
String json = gson.toJson(phone);

仅需一行代码就能把对象转成Json格式的字符串

{"name":"Android","price":1000}

这里为了方便查看,我们可以创建一个临时文件,选择JSON,用于查看Json字符串

image-20191203142249579.png

把刚刚的字符串粘贴到这,再用代码格式化查看就行了

{
  "name": "Android",
  "price": 1000
}

当然我们也可以把Json格式的字符串转成对象

Gson gson = new Gson();
String json = "`{\"name\":\"Android\",\"price\":1000}";
Phone phone = gson.fromJson(json, Phone.class);

上面都是单个对象,下面以数组为例

[
  {
    "name": "Android",
    "price": 1000
  },
  {
    "name": "Android",
    "price": 1000
  }
]

可以看到数组是用一对[]包裹,中间每一对{}代表一个对象,同理反过来也是一样的

Gson gson = new Gson();
String json = "[{\"name\":\"Android\",\"price\":1000},{\"name\":\"Android\",\"price\":1000}]";
Phone[] phones = gson.fromJson(json, Phone[].class);

当然也可以转换成列表:List<Phone> list = Arrays.asList(phones);

那么如果直接把列表转换成Json字符串以及直接把Json字符串转成列表呢?

Gson gson = new Gson();
Phone phone = new Phone("Android", 1000);
Phone phone1 = new Phone("Android", 1000);
List<Phone> list = new ArrayList<>();
list.add(phone);
list.add(phone1);
String json = gson.toJson(list);

可以看到列表转换成Json字符串也是能够实现的,但是反过来就不行了

image-20191203144416253.png

但是是有办法解决的,在我们使用fromJson()时,可以看到有以下参数列表:

image-20191203144517539.png

所以我们可以使用Type类来实现

Gson gson = new Gson();
String json = "[{\"name\":\"Android\",\"price\":1000},{\"name\":\"Android\",\"price\":1000}]";
Type type = new TypeToken<List<Phone>>() {}.getType();
List<Phone> list = gson.fromJson(json, type);

可以看到Json字符串转换成了对应的列表

关于序列化的使用差不多就这些了

相关文章

网友评论

      本文标题:序列化:Serializable、Parcelable、JSON

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