1, Generic overview
- Generics refer to "parameterized types."
- That is, the data type of some parameters is replaced by a generic type. When using or calling, the specific data type is assigned to the generic type
- Mode of use
- Generics are defined in angle brackets. Multiple generics can be defined at the same time, separated by commas
- Such as < T >, < T, V >
- Generics are defined in angle brackets. Multiple generics can be defined at the same time, separated by commas
2, Generic category
1. Generic class
- When defining a class, define generics after the class name
- Used quite a lot
- After jdk1.7, the generics in the angle brackets after the new object can be omitted. You only need to define the generics after defining the variable data type
- give an example
//Define a class and use generics public class Test<T>{ //The parameter type of the data is specified by the generic type public T data; public T getData(){ return this.data; } } class Demo{ public static void main(String[] args){ Test<String> t = new Test<>(); //perhaps Test<String> t = new Test<String>(); } }
2. Generic interface
- When defining an interface, write generics after the interface name
- Implementation classes can be defined in two ways when implementing interfaces
- Specifies the type of the generic
- Define generics when creating implementation class instances
- Preserve generics
- When defining an implementation class, you also need to add generics after the class name
- When creating an implementation class instance, you need to specify the specific type of the generic
- Specifies the type of the generic
- give an example
public class Demo1 { public static void main(String[] args) { //t1 specifies the data type, which is String Test1 t1 = new Test1(); t1.data = "hello"; System.out.println(t1.say()); //t2 you need to specify a specific data type Test2<String> t2 = new Test2(); t2.data = "hello"; System.out.println(t2.say()); } } //Defining generic interfaces interface Test<T>{ T say(); } //Method 1 of implementing generic interface: specify the type of generic class Test1 implements Test<String>{ public String data; @Override public String say() { return data; } } //Implementation of generic interface mode 2: retain generics //You also need to define generics after the class name class Test2<T> implements Test<T>{ public T data; @Override public T say() { return data; } }
3. Generic method
- grammar
Permission modifier (static) generic return type Method name (parameter list){
}
- The genericity of a generic method is valid only within the region of the method
- give an example
public class Demo2 { public static void main(String[] args) { A.say("hello"); A.say(123); } } class A{ public static <T> void say(T a){ System.out.println(a); } }
3, Generic restricted type
- When using generics, you can specify the qualified region of generics
- grammar
< T extends Class or interface 1& Interface 2 >
- give an example
public class Demo3 { public static void main(String[] args) { // Plate < string > P1 = new plate < string > (); / / error Plate<Apple> p2 = new Plate<>(); //No error reporting } } //Define fruit interface interface Fruit{} //Apple class implements fruit interface class Apple implements Fruit{} //Class, generic T can only be Fruit or its subclass class Plate<T extends Fruit>{}
4, Generic wildcard
- The wildcard of a generic type refers to "?", which is used in place of a method specific type argument
< ? extends Parent> Specifies the upper bound of the generic, i.e.? Can only be a parent or its subclass
When creating objects, the generics behind new also need to define specific data types
< ? super Child> Specifies the lower bound of the generic, i.e.? Can only be child or its parent class
When creating objects, the generics behind new also need to define specific data types
< ? > Specifies unrestricted generic types, and specifies specific parameter types when calling
- give an example
package fanxing; public class Demo3 { public static void main(String[] args) { // Plate < fruit > P = new plate < Apple > (); / / an error is reported unless it is written in the following way //Generic upper bound. The following generic must be Fruit or its subclass Plate<? extends Fruit> p1 = new Plate<Apple>(); //Lower bound of generics. The following generics must be Apple or its parent class Plate<? super Apple> p2 = new Plate<Fruit>(); } } //Fruit interface interface Fruit{} //Apple class implements fruit interface class Apple implements Fruit{} //Plate class class Plate<T>{}
5, Role of generics
- Improve code reuse rate
- For example, in method overloading, you may need to overload a large number of methods. These overloaded methods only have different parameter types. At this time, you can use generic instead of overloading, and you only need to change the data type of the input parameter into generic. Therefore, you can improve the reuse rate of the code and avoid writing too much duplicate code
- Types in generics are specified when used, and no additional cast operations are required
- Type safe, the compiler checks the type for errors
6, Precautions
- In the compilation process, after the generic results are correctly verified, the relevant information of the generic will be erased, and the methods of type checking and type conversion will be added at the boundary where the object enters and leaves the method
- That is, generics are only valid during compilation and do not enter the runtime phase