Google AutoValue详解

背景

首先说Android Model,在开发中网络请求,以及数据库操作等,我们都会定义一个Model,不同人对这个的说法不一样,比如有Entry,Bean,Pojo。
通常对于实体类,我们需要做如下几件事情:

  • 构成方法:自定义构造方法,如果实体比较复杂,可能会用到工厂模式或者是建造者模式
  • 序列化:比如实现Serializable接口,Parcelable接口。
  • Json解析:有时候直接使用的是json数据,比如@SerializedName注解。
  • 自定义方法:对Model的字段有setter,getter方法,toString的实现,在处理hash的时候,需要实现equals和hashcode方法。
    这些实际上eclipse及Android Studio都已经帮我们做好了。

通常的我们看到的java bean是这样的

public class NvramInfo {

    private String key;
    private String value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NvramInfo nvramInfo = (NvramInfo) o;
        return Objects.equals(key, nvramInfo.key) &&
                Objects.equals(value, nvramInfo.value);
    }

    @Override
    public int hashCode() {

        return Objects.hash(key, value);
    }

    @Override
    public String toString() {
        return "NvramInfo{" +
                "key='" + key + '\'' +
                ", value='" + value + '\'' +
                '}';
    }
}

简介

为了是的java bean的看起来更加简介优雅,我们来看看Google AutoValue 如何处理java bean的。
那么AutoValue是什么呢?来看下官方总结解释的:
一个生成Java不可变的值类型工具,仔细研读源代码后,使用的技术是Java Apt

AutoValue - Immutable value-type code generation for Java 1.6+.

简单使用

基于Android Studio 3.1.2, 支持Android的gradle插件版本为3.0.1
在工程根目录下添加如下gradle插件版本

dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
    }

app Module中添加如下依赖:

annotationProcessor 'com.google.auto.value:auto-value:1.5.2'
    compileOnly 'com.google.auto.value:auto-value:1.5.2'

通过AutoValue构造的Java Bean如下:

package com.grandstream.gsmarket.data.entity;

import android.os.Parcelable;

import com.google.auto.value.AutoValue;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;

@AutoValue
public abstract class AppInfo implements Parcelable {
    /**
     * @Description: TODO(添加属性注释)
     */
    //private static final long serialVersionUID = 1L;

    public static JsonAdapter<AppInfo> jsonAdapter(Moshi moshi) {
        return new AutoValue_AppInfo.MoshiJsonAdapter(moshi);
    }

    public static Builder builder() {
        return new AutoValue_AppInfo.Builder();
    }

    /**
     * @Description: 主键id
     */
    public abstract String appname();

    public abstract String appcode();

    public abstract String version();

    public abstract String size();

    public abstract String packagename();

    public abstract String downloadurl();

    @AutoValue.Builder
    public abstract static class Builder {
        public abstract Builder appname(String appname);

        public abstract Builder appcode(String appcode);

        public abstract Builder version(String version);

        public abstract Builder size(String size);

        public abstract Builder packagename(String packagename);

        public abstract Builder downloadurl(String downloadurl);


        public abstract AppInfo build();
    }
}

在上面的java bean的构造中,我们采用了建造者模式完成,同时实现了Parcelable 及moshi Json的转化功能。
建立AutoValue与moshi Json的关系需要如下依赖:

    implementation 'com.ryanharter.auto.value:auto-value-moshi-annotations:0.4.3'
    annotationProcessor 'com.ryanharter.auto.value:auto-value-moshi:0.4.3'
    implementation 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.5'
    annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5'

编译后生成的相关类关系图
类关系生成图
从类关系图可以看出,最终会生成一个AutoValue_AppInfo的类,实现所有的注解功能。在实际使用,创建对象时候,通过静态构造方法完成

public static Builder builder() {
        return new AutoValue_AppInfo.Builder();
    }

查看最终类AutoValue_AppInfo代码可以看出,所有的变量及最终的类都是final类型的,代码里同时也实现了equals、hashcode、toString方法。

Immutable/Value types
刚刚上面说到,所有的字段都是final类型,那么而且实现类也是final的,有个专业术语叫Immutable。一个数据对象一旦构造完成,就再也无法修改了。这样有什么好处呢?最大的好处就是多线程访问可以省去很多同步控制,因为它们是不可变的,一旦构造完成,就不会存在多线程竞争访问问题了。多线程最麻烦的处理就是控制好读写问题,如果大家都是读,那么就不存控制了,所以省去了很多同步操作。

举个Java中的例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。

Immutable objects 比传统的mutable对象在多线程应用中更具有优势,它不仅能够保证对象的状态不被改变,而且还可以不使用锁机制就能被其他线程共享。
总结下Immutable对象的优缺点:
优点
1. Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享
2. Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享
3. Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用
4. Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
缺点
Immutable也有一个缺点就是会制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,字符串就是一个典型的例子,它会创造很多的垃圾,给垃圾收集带来很大的麻烦。当然这只是个极端的例子,合理的使用immutable对象会创造很大的价值。

详细使用及原理戳这里

猜你喜欢

转载自blog.csdn.net/u011897062/article/details/80378476
今日推荐