First, an overview:
Generics play an important role in java and are widely used in object-oriented programming and various design patterns.
What is generics
Generics are "parameterized types". When it comes to parameters, the most familiar thing is to define a method with tangible parameters, and then pass arguments when calling the method. So how do you understand parameterized types? As the name implies, the type is parameterized from the original specific type, similar to the variable parameter in the method, in which case the type is also defined as a parameter form (which can be called a type parameter), and then the specific type (type parameter) is passed in when using/calling.
The essence of generics is to parameterize types (in the absence of creating new types, the types specified by generics are used to control the specific restrictions on parameters). That is to say, in the process of generic use, the data type of operation is designated as a parameter. This parameter type can be used in classes, interfaces and methods, which are called generic class, generic interface and generic method respectively.
Benefits of generic approaches:
Generic methods enable this method to change independently of classes. We can write a generic method that receives different types of parameters when invoked. Depending on the type of parameters passed to generic methods, the compiler handles each method call appropriately.
Second, the basic guiding principles:
Whenever you can, you should try to use generic methods. That is to say, if generic methods can be used instead of generizing the whole class, then only generic methods should be used, because it can make things clearer. In addition, for a static method, the type parameters of generic classes cannot be accessed. Therefore, if the static method needs to use generic capabilities, it must become a generic method.
Third, rules for defining generic methods:
1) All generic method declarations have a type parameter declaration section (separated by angle brackets) that precedes the method return type (in the following example, <E>).
2) Each type parameter declaration contains one or more type parameters separated by commas. A generic parameter, also known as a type variable, is an identifier used to specify a generic type name.
3) Type parameters can be used to declare return value types, and can be used as placeholders for actual parameter types obtained by generic methods.
4) The declaration of generic method bodies is the same as that of other methods. Note that type parameters can only represent reference types, not primitive types (such as int,double,char, etc.).
/** * public The < T > between the return value and the return value is very important and can be understood as declaring this method generic. * Only methods declaring < T > etc. are generic methods, and member methods using generic types in generic classes are not generic methods. * <T>It indicates that generic type T will be used in the method, and then generic type T can be used in the method. * As with the definition of generic classes, T can be written as arbitrary identifiers here. Common parameters such as T, E, K, V are often used to represent generics. */ public class GenericMethods { public <T> void genericMethod1(T t){ System.out.println(t.getClass().getName()); } public <T> T genericMethod2( Class<T> tClass ) throws InstantiationException , IllegalAccessException { T t = tClass.newInstance(); return t; } public static <T> void genericMethod3( T[] inputArray ) { // Output Array Elements for ( E element : inputArray ){ System.out.printf( "%s ", element ); } } }
4. Examples of generic methods:
To illustrate, when defining a generic method, you must add a < T > before the return value to declare that it is a generic method and holds a generic T before you can use generic T as the return value or parameter type of the method.
A generic class specifies the specific type of a generic type when instantiating a class, while a generic method specifies the specific type of a generic type when calling a method.
Generic types are used in the definition of classes and are called generic classes. Generics allow you to open the same interface to a group of classes. The most typical container classes are List, Set, Map.
Generic methods can be used anywhere and in any scenario, but there is a very special case. When generic methods appear in generic classes, let's take another example to see:
/** * This is a generic class */ class GenericClassDemo<T> { /** * This is not a generic method, but uses the declared T in the generic class. */ public void show1(T t){ System.out.println(t.toString()); } /** * The generic method uses generic E, which can be of any type. It can be the same type as T, or it can be different. * Because the following generic methods declare generics <E> at the time of declaration, generics are not declared even in generic classes. * The compiler can also correctly identify the generics identified in the generic method. */ public <E> void show2(E e){ System.out.println(e.toString()); } /** * A generic method is declared in the generic class, using generic T. Note that this T is a completely new type. * T can not be of the same type as T declared in generic classes. */ public <T> void show3(T t){ System.out.println(t.toString()); } }
Generic methods and variable parameters
Generic methods and variable parameter lists can coexist well:
public class GenericMethodTest { public <T> void printArgs( T... args ){ for(T t : args){ System.out.print(t + " "); } } public static <T> List<T> toList(T... args){ List<T> result = new ArrayList<T>(); for(T item:args) result.add(item); return result; } public static void main(String[] args) { GenericMethodTest gmt = new GenericMethodTest(); gmt.printArgs("A","B"); // A B List ls = GenericMethodTest.toList("A"); System.out.println(ls); // [A] ls = GenericMethodTest.toList("A","B","C"); System.out.println(ls); // [A,B,C] } }
Static methods use generics
Static methods cannot access generics defined on classes. If the reference data type of static method operations is uncertain, generics must be defined in methods. That is, if a static method is to use generics, it must also be defined as a generic method.
public class GenericTest<T> { /** * Additional generic declarations need to be added if static methods using generics are defined in classes * Even static methods cannot use generics already declared in generic classes (this method needs to be defined as generic methods) * For example: public static void generic method (T) {.}, when the compiler will prompt error information: * "StaticGenerator cannot be refrenced from static context" */ public static <T> void genericMethod(T t) { // ... } }