“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
One, foreword
-
Generalization: You can use T to represent any type, so many important classes, such as collections frameworks, have become generic, which brings many benefits.
-
Type safety: Using generics enables the compiler to know the type limits of variables, which in turn allows you to verify type assumptions to a higher degree. If you don’t use generics, you must use casts, which are unsafe and can cause ClassCast exceptions at runtime, which can be detected at compile time if you use generics.
-
Eliminate casts: Generics eliminate many casts from source code, which makes the code more readable and reduces the chance of errors.
There are many places where generics are used in the Android source code.
Second, the use of
2.1 Java Generic interfaces
Define generics in interfaces as follows:
public interfaceInterface name < generic type >{}Copy the code
2.1.1 definition
Usage scenario: After a network request, the calling interface passes in an entity class (unknown), and returns the instance after a successful request. As follows:
public interface HttpResponse<T> {
// The request succeeded
void onSuccess(T bean);
// The request failed
void onError(String response);
}
Copy the code
2.1.2 use
//HomeBean.class
new HttpResponse<HomeBean>() {
...
};
//BannerBean.class
new HttpResponse<BannerBean>() {
....
};
Copy the code
This T can be either a HomeBean or a BannerBean.
2.2 Java generic Classes
Define generics on classes as follows:
public classClass name < generic type >{}Copy the code
2.2.1 definition
Usage scenario: We use more places. For example, the data returned by a network request (often defined as generic) looks like this:
public class ResponseData<T> {
private int errorCode;
private String errorMsg;
private T data;
}
Copy the code
2.2.2 use
@GET("banner/json")
Call<ResponseData<List<HomeBanner>>> homeBannerRetrofit();
@POST("user/register")
@FormUrlEncoded
Call<ResponseData<RegisterData>> registerRetrofit(@FieldMap Map<String,String> map);
Copy the code
This T can be either List
or RegisterData.
2.3 Java generic methods
Define generics on classes as follows:
public< generic type > return type method name < generic type variable name > {}Copy the code
2.3.1 definition
Usage scenario: We use more places. For example, the data returned by a network request (often defined as generic) looks like this:
public class Test {
public <T>T name(T data){
return data;
};
}
Copy the code
2.3.2 use
Test test = new Test();
HomeBean homeBean = test.name(new HomeBean());
RegisterData registerData = test.name(new RegisterData());
Copy the code
This T can be either a HomeBean or RegisterData.
2.4 Java generic erasure and related content
At compile time, all generic information is erased, and the type information in the generics is not included in the generated bytecode.
Against 2.4.1 ArrayList source
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess.Cloneable.java.io.Serializable
{}Copy the code
This is clearly a generic class. Let’s look at a set of examples:
List<String> list = new ArrayList<>();
list.add("abc");
List<Integer> list1 = new ArrayList<>();
list1.add(123);
List<UserBean> list2 = new ArrayList<>();
list2.add(new UserBean(20."sc"));
MLog.e(String.valueOf(list.getClass()));
MLog.e(String.valueOf(list.getClass() == list1.getClass()));
MLog.e(String.valueOf(list.getClass() == list2.getClass()));
MLog.e(String.valueOf(list1.getClass() == list2.getClass()));
Copy the code
Print result:
E/---mlog----: class java.util.ArrayList
E/---mlog- :true
E/---mlog- :true
E/---mlog- :true
Copy the code
You will then see the generic
in ArrayList
erased. Therefore, all the objects are added in the form of add.
2.5 Java generic wildcards
2.5.1 T, E, K, V
2. Something established:
- T (type) indicates a specific Java type
- K and V are key values in Java key values
- E stands for Element
It can also be defined as other letters, but it is not recommended.
2.5.2 <? extends T>
Upper bound wildcard
Upper bound wildcard:
means that the upper limit of a type is itself, so wildmatched parameterized types may be T or subclasses of T.
The code is as follows:
private void test(a){
// List
listZuZong = new ArrayList
(); / / an error
List<? extends YeYe> listYeYe = new ArrayList<YeYe>();
List<? extends YeYe> listBaBa = new ArrayList<BaBa>();
List<? extends YeYe> listSuSu = new ArrayList<SuSu>();
List<? extends YeYe> listZiji = new ArrayList<Ziji>();
};
class ZuZong{}class YeYe extends ZuZong{}class BaBa extends YeYe{}class SuSu extends YeYe{}class Ziji extends BaBa{}Copy the code
2.5.3 <? super T>
Upper bound wildcard
Lower bound wildcard:
denotes that the lower bound of a type is itself, so wildmatched parameterized types may be T or a superclass of T, up to Object.
The code is as follows:
List<? super YeYe> listObject = new ArrayList<Object>();
List<? super YeYe> listZuZong = new ArrayList<ZuZong>();
List<? super YeYe> listYeYe = new ArrayList<YeYe>();
// List
listBaBa = new ArrayList
(); / / an error
// List
listSuSu = new ArrayList
(); / / an error
// List
listZiji = new ArrayList
(); / / an error
Copy the code
2.5.4 <? >
Unbounded wildcard
Unbounded wildcard: Any type.
The code is as follows:
List<? > listObject =newArrayList<Object>(); List<? > listZuZong =newArrayList<ZuZong>(); List<? > listYeYe =newArrayList<YeYe>(); List<? > listBaBa =newArrayList<BaBa>(); List<? > listSuSu =newArrayList<SuSu>(); List<? > listZiji =new ArrayList<Ziji>();
Copy the code