“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