Initial understanding of the generic nature of Java

  • 2020-04-01 04:25:45
  • OfStack

In Java SE1.5, a new feature was added: generics (type in Japanese). What is generic? In layman's terms, it is generally used to specify the type of an object to operate on, rather than a fixed type. The essence of generics is to parameterize the data type being manipulated, that is, to specify the data type as a parameter. This parameter type can be used in class, interface, and method definitions.
 
One, why use generics?
        In previous J2SE versions, in the absence of generics, it was common to use the Object type to manipulate multiple types of data. At this time, the most common operation is to cast the data against the Object, and this conversion is based on the developer's specific data type (such as Object to String). If the type is inconsistent, the compiler does not report errors during compilation, but errors occur at run time.
      The advantage of using generics is that it performs type safety checks at compile time and all conversions are mandatory and implicit at run time, greatly increasing the rate of code reuse.
 
Two, definition & use
  The naming style of type parameter is:
  It is recommended that you use concise names for formal type parameters (single characters, if possible). It is best to avoid lowercase letters, which makes it common with others
  The formal parameters of.
  There is no more specific type than T for type at any time. This is often seen in generic methods. If there are multiple type parameters, we
  You might use a letter in the alphabet next to a T, such as an S.
  If a generic function appears in a generic class, it is best to avoid mixing the type arguments of a method with the type arguments of a class by using the same name
  Xiao. The same is true for internal classes.
 
1. Define a class with a type parameter
  When defining a class with type parameters, < > Specifies the name of one or more type parameters, as well as the name of the type parameter
  Value range is limited, and multiple type parameters are separated by,.
  After defining the type parameters, you can use the type parameters almost anywhere in the class after the defined location (except for static blocks, static properties, and static methods),
  Just like with normal types.
  Note that type parameters defined by a parent class cannot be inherited by a subclass.


 public class TestClassDefine<T, S extends T> {
   .... 
 }

 
2. Define the method of parameter to be type
  When defining a method with type parameters, after the visible range modifier (such as public), < > Specifies the name of one or more type parameters,
  At the same time, it is also possible to limit the value range of type parameters.
  After you have defined the type parameters, you can use the type parameters anywhere in the method after the defined location, just as you would with a normal type.
  Such as:


 public <T, S extends T> T testGenericMethodDefine(T t, S s){
   ...
 }

  Note: a method with type parameters is defined. The main purpose of the ride is to express the relationship between multiple parameters and return values. For example, the continuation of T and S in this example
  The type of the return value is the same as the value of the first type parameter.
  If you simply want to achieve polymorphism, use wildcard resolution in preference. See the following section for the contents of wildcards.


 public <T> void testGenericMethodDefine2(List<T> s){
   ...
 }

  Should be changed to


 public void testGenericMethodDefine2(List< ? > s){
   ...
 }

 
3. Type parameter assignment
  When assigning type parameters to a class or method, all type parameters are required. Otherwise, you get a compilation error.
 
4. Assign type parameters to classes with type parameters
  There are two ways to assign type parameters to classes with type parameters
  The first time you declare a class variable or instantiate it. For example,


 List<String> list;
 list = new ArrayList<String>;

  Second class inheritance or interface implementation. For example,


 public class MyList<E> extends ArrayList<E> implements List<E> {...} 

 
5. Assign values to methods with type parameters
  When a generic method is called, the compiler automatically assigns a value to the type parameter and reports a compilation error when the assignment is unsuccessful. For example,


 public <T> T testGenericMethodDefine3(T t, List<T> list){
   ...
 }
 public <T> T testGenericMethodDefine4(List<T> list1, List<T> list2){
   ...
 }
 
 Number n = null;
 Integer i = null;
 Object o = null;
 testGenericMethodDefine(n, i);//So T is Number and S is Integer
 testGenericMethodDefine(o, i);//T is Object, S is Integer
 
 List<Number> list1 = null;
 testGenericMethodDefine3(i, list1)//Now T is Number
 
 List<Integer> list2 = null;
 testGenericMethodDefine4(list1, list2)//A compiler error

 
6. A wildcard
  In the two sections above, you can assign specific values to type parameters. In addition, you can assign uncertain values to type parameters. For example,


 List<?> unknownList;
 List<? extends Number> unknownNumberList;
 List<? super Integer> unknownBaseLineIntgerList; 

  Note: in the Java collection framework, for the container class whose parameter value is unknown type, only the element can be read, and the element cannot be added to it.
  Because its type is unknown, the compiler cannot tell whether the type of the added element is compatible with the type of the container, with the exception of NULL


 List<String> listString;
 List<?> unknownList2 = listString;
 unknownList = unknownList2;
 listString = unknownList;//Compile error

 
7. Array paradigm
  You can declare an array using a class with a generic parameter value, but you cannot create an array


 List<Integer>[] iListArray;
 new ArrayList<Integer>[10];//Compile-time error

 
Three, extension,
1. Extends statement
Using the extends statement limits the scope of generic parameters. Such as:
< T extends collection> , indicates that the scope of use of the generic parameter is all calss that implement the collection interface. If you pass in an < String> An error occurs in program compilation.
2. Super statement
The super statement, like extends, limits the scope of generic parameters. The difference is that super limits the generic parameter to only the upper parent of the specified class.
For example, < T super List> , indicating that the generic parameter can only be a List and its upper parent.
3. Wildcards
The purpose of using wildcards is to address the disadvantage that generic parameters are limited and cannot be dynamically determined based on the instance.
For example: public class SampleClass < T extends S> {... }
Suppose A, B, C... All of these 26 classes implement the S interface. We need to use the generic parameters of these 26 class types. So what happens when you instantiate it? Write in turn


SampleClass<A> a = new SampleClass();
SampleClass<B> a = new SampleClass();
 ... 
SampleClass<Z> a = new SampleClass();

This is obviously redundant, so why not use Object instead of generics?
Don't worry. Let's just use the wildcard.


SampleClass<? Extends S> sc = new SampleClass();

 
Only need to declare a sc variable, very convenient!


Related articles: