泛型又叫参数化类型,其主要描述的是在进行类,接口,方法的界说时,运用笼统的数据结构或许进行简略的束缚,其真实装载的数据结构或目标联系由开发者在创立该类,接口,方法时完成,Android开发中最典型的泛型运用便是Gson解析后端回来数据的场景。

网络恳求数据解析中的泛型

假定服务器接口界说,所有接口统一回来如下的json数据:

// data为一个JsonObject
{"code":"0","message":"success","data":{}}
// data为一个JsonArray
{"code":"0","message":"success","data":[]}

其间code代表恳求的错误码,message代表接口恳求信息,data代表接口回来的数据结构,那么咱们能够预知到在恳求多个接口时,data域中的内容也是不一样的,如果依照一般实体解析,咱们每个实体类中都会有code,message这两个成员,那么有没有办法进行归一呢?这儿就要用到泛型了,咱们运用泛型界说上述接口回来所对应的实体如下所示:

// 泛型T代表data所对应的类型,有可能是Object,也有可能是List,详细由调用方指定
public class HttpResponse <T>{
    private String code;
    private String message;
    private  T data;
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}

Gson解析运用TypeToken来指定这儿泛型T的类型以完结后段回来数据解析,代码段如下:

String responseStr = response.body().string();
// 这儿的String就代表data是一个字符串,对应上述实体类中的泛型T
Type type = new TypeToken<HttpResponse<String>>(){}.getType()
HttpResponse httpResponse = new Gson().fromJson(responseStr,type);

容器类中的泛型

Java自身内部也有许多泛型声明,比方咱们的各种容器类,如ArrayList,List,Collection等,Collection的界说如下所示:

public interface Collection<E> extends java.lang.Iterable<E> {
public int size();
public boolean isEmpty();
public boolean contains(@libcore.util.Nullable java.lang.Object o);
@libcore.util.NonNull public java.util.Iterator<@libcore.util.NullFromTypeParam E> iterator();
public java.lang.@libcore.util.Nullable Object @libcore.util.NonNull [] toArray();
public <T> T @libcore.util.NonNull [] toArray(T @libcore.util.NonNull [] a);
public boolean add(@libcore.util.NullFromTypeParam E e);
public boolean remove(@libcore.util.Nullable java.lang.Object o);
public boolean containsAll(@libcore.util.NonNull java.util.Collection<?> c);
public boolean addAll(@libcore.util.NonNull java.util.Collection<? extends @libcore.util.NullFromTypeParam E> c);
public boolean removeAll(@libcore.util.NonNull java.util.Collection<?> c);
public default boolean removeIf(@libcore.util.NonNull java.util.function.Predicate<? super @libcore.util.NullFromTypeParam E> filter) { throw new RuntimeException("Stub!"); }
public boolean retainAll(@libcore.util.NonNull java.util.Collection<?> c);
public void clear();
public boolean equals(@libcore.util.Nullable java.lang.Object o);
public int hashCode();
@libcore.util.NonNull public default java.util.Spliterator<@libcore.util.NullFromTypeParam E> spliterator() { throw new RuntimeException("Stub!"); }
@libcore.util.NonNull public default java.util.stream.Stream<@libcore.util.NullFromTypeParam E> stream() { throw new RuntimeException("Stub!"); }
@libcore.util.NonNull public default java.util.stream.Stream<@libcore.util.NullFromTypeParam E> parallelStream() { throw new RuntimeException("Stub!"); }
}

从这儿能够看出泛型类在被继承时,泛型数据是要发生传递的,A类中声明一个泛型T,B是A的字类,其最少也要声明一个泛型,以传递给A,确保A能够正常初始化

架构规划中的泛型

在MVP的基础规划中,咱们通过声明BaseView,BasePresenter,BaseModel,然后在其各自的子类中完成相对应的事务代码,构成一套代码规范,将一些公共逻辑封装在BaseXXX中。

但随着开发团队的人员更迭,代码量的增加,新同学在运用MVP时可能会只运用三个基类中的一个或两个,乃至调配自己完成的其他BaseXXX类,导致事务逻辑反常,那么有没有办法构成束缚,使得这三个绑定在一起运用呢?此刻就需要用到泛型了。

以泛型搭建束缚,完成的IBaseView,IBasePresenter,IBaseModel如下所示:

public interface IBaseView  <T extends BasePresenter>{
}
public interface IBasePresenter <V extends BaseView,M extends BaseModel>{
}
public interface IBaseModel {
}

对应的Base完成类,BaseView,BasePresenter,BaseModel如下图所示

public class BaseView<P extends BasePresenter> implements IBaseView<MainPresenter> {
}
public class BasePresenter<V extends BaseView,M extends BaseModel> implements IBasePresenter<V,M>{
}
public class BaseModel implements IBaseModel{
}

事务完成的View,Presenter,Model如下所示:

public class MainView extends BaseView<MainPresenter>{
}
public class MainPresenter extends BasePresenter<MainView,MainModel>{
}
public class MainModel extends BaseModel {
}

从代码能够看出咱们运用泛型完成了,View,Presenter,Model三者之间的持有相关依赖联系,确保其他开发者能依照咱们规划的规范运用这三个类。

<?>和 < T > 有什么区别?

泛型符号 含义 补白
< T > 通配特定的一种类型,在界说时,类型确认且共同,如List strList = new ArrayList(); /
<?> 通配恣意类型,假定ArrayList<?> arrays= new ArrayList();这种书写建立,那么代表arrays中能够装载恣意类型的目标 /
  • <?extends E>或:表示所通配的类型为E或许E的子类型
  • <?super E>或:表示通配的类型为E或E的父类型