背景
首先说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对象会创造很大的价值。