泛型又叫参数化类型,其主要描述的是在进行类,接口,方法的界说时,运用笼统的数据结构或许进行简略的束缚,其真实装载的数据结构或目标联系由开发者在创立该类,接口,方法时完成,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的父类型