1, Generic class usage
Generic class usage: declare the generic type before use. If the generic type is not declared, it means that the generic type of this class is Object type;
Generic class code:
public class Student<T> { private String name; private int age; /** * The data type is unknown * Using a generic representation, the runtime determines the type */ private T data; public Student(String name, int age, T data) { this.name = name; this.age = age; this.data = data; } }
Indicate generic type: Specifies that the generic type of the generic class is String type, so the location where T type is used in this class must be String type. The generic declaration of the generic class must be declared after the class name when used;
// Specifies that the generic type of the generic class is a String type // In this class, where T type is used, it must be String type // The generic declaration of a generic class, which is declared after the class name when used Student<String> student = new Student("Tom", 16, "Cat"); String data = student.getData();
Do not specify generic type: if the generic type is not specified, the generic type defaults to Object type; As shown in the following example, the obtained generic type variable is also Object type and needs to be forcibly converted to String type;
// If the generic type is not specified // The generic type defaults to Object type Student student1 = new Student("Tom", 16, "Cat"); // The obtained generic type variable is also an Object type and needs to be forcibly converted to String String data1 = (String) student1.getData();
2, Generic method usage
Generic method: pass String as parameter to the following generic method, and the type of T in the generic method is String type;
public <T, A> T getData2(T arg){ T data = arg; return data; }
Specify generic method: specify the generic class of the generic method, the generic declaration of the generic method, and the declaration in front of the method name when calling; This usage is rare;
// Specifies the generic class of the generic method // Generic declaration of a generic method, declared before the method name when called student.<String, Integer>getData2("Mouse");
Do not specify generic methods: generic types can also not be declared in generic methods. The passed in parameters are generic T types. If String is set for the passed in parameters, the generic T is implicitly set to String type;
// Generic types can also not be declared in generic methods // The parameter passed in is a generic T type // If String is set for the incoming parameter, the generic T is implicitly set to String type String data2 = student.getData2("Mouse");
3, Generic wildcard <? >
If the current generic type is uncertain, use? As a wildcard, this usage is the same as specifying a generic type as an Object type;
? Examples of wildcard usage:
// Use <? > Wildcards as generics // The generic type is specified as the Object type by default Student<?> student2 = new Student("Tom", 16, "Cat"); String data2 = (String) student1.getData();
above? Wildcard usage is equivalent to the following usage without specifying generics:
// If the generic type is not specified // The generic type defaults to Object type Student student1 = new Student("Tom", 16, "Cat"); // The obtained generic type variable is also an Object type and needs to be forcibly converted to String String data1 = (String) student1.getData();
4, Generic security check
Notice below 2 2 For the usage of 2 generic types, the first method is recommended;
// Generic security check // Recommended writing Student<String> student3 = new Student<>("Tom", 16, "Cat"); // Not recommended Student student4 = new Student<String>("Tom", 16, "Cat");
Creating objects with the new keyword occurs at runtime, that is, the new student < string > ("Tom", 16, "cat") code is executed at runtime, which simply does not play the role of compile time security check. In terms of security check, this writing has no meaning;
Take the List generic as an example:
- Example of security check during compilation:
// The compiler checks at compile time List<String> list1 = new ArrayList<>(); list1.add(1);
The following errors will be reported;
- No security check at compile time example:
// The compiler does not check at compile time List list2 = new ArrayList<String>(); list2.add(1);
There is no error in this code;
5, Complete code example
1. Generic class / method
/** * Generic class * This T type is used as a parameter * T Is a parameterized type that can be passed in externally * * @param <T> */ public class Student<T> { private String name; private int age; /** * The data type is unknown * Using a generic representation, the runtime determines the type */ private T data; public Student(String name, int age, T data) { this.name = name; this.age = age; this.data = data; } /** * The method is not generic * This method is a normal method, and the return value type is T type * @return */ public T getData() { return data; } public void setData(T data) { this.data = data; } /** * Generic method is to pass a type as a parameter * Method specifies a generic type, which is written as follows:; * * The method is generic * Method specifies 2 generics * Number of generics. There can be many generics * Multiple generics are separated by commas * * The generic T specified by the generic method has nothing to do with the generic T in the class * The two T's can be of different types * * Generic T defined in generic method * T with parameter type * T of return value type * Method internal T * All of the same type * * It has nothing to do with T in generic classes * * @param <T> * @param <A> * @return */ public <T, A> T getData2(T arg){ T data = arg; return data; } public <T> T getData4(T arg){ T data = arg; return data; } /** * If you use generics in a class in a static method * This use is wrong * * If you must use generic T in static methods * Then the generic T must be a generic of a static method * Cannot be a generic type of a class * * @param arg * @return */ public static <T> T getData3(T arg){ T data = arg; return data; } }
2. main function
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // Specifies that the generic type of the generic class is a String type // In this class, where T type is used, it must be String type // The generic declaration of a generic class, which is declared after the class name when used Student<String> student = new Student("Tom", 16, "Cat"); String data = student.getData(); // If the generic type is not specified // The generic type defaults to Object type Student student1 = new Student("Tom", 16, "Cat"); // The obtained generic type variable is also an Object type and needs to be forcibly converted to String String data1 = (String) student1.getData(); // Use <? > Wildcards as generics // The generic type is specified as the Object type by default Student<?> student2 = new Student("Tom", 16, "Cat"); String data2 = (String) student1.getData(); // Generic security check // Recommended writing Student<String> student3 = new Student<>("Tom", 16, "Cat"); // Not recommended Student student4 = new Student<String>("Tom", 16, "Cat"); // Specifies the generic class of the generic method // Generic declaration of a generic method, declared before the method name when called student.<String, Integer>getData2("Mouse"); // Generic types can also not be declared in generic methods // The parameter passed in is a generic T type // If String is set for the incoming parameter, the generic T is implicitly set to String type String data3 = student.getData2("Mouse"); // The compiler checks at compile time List<String> list1 = new ArrayList<>(); list1.add(1); // The compiler does not check at compile time List list2 = new ArrayList<String>(); //list2.add(1); } }