catalogue
2.2 instantiate a generic class
2.4.2 implementation of generic methods
3.1 basic data type and its corresponding packaging type
Today, let's talk about generics. First, let's talk about what generics are?
1. What is generics?
In our previous study of java basic syntax, the types of function parameters are basically: basic data type and reference data type. The parameter transfer process of basic data type is that the actual parameter transfers the value to the formal parameter (when defining the formal parameter, the type needs to be defined in front of the formal parameter); The reference data type passes the address to the formal parameter through the argument.
So can we pass a type as a parameter? Obviously.
Generally speaking, generic: it is applicable to many types. In terms of code, it is parameterization of types.
2. Generics
Let's implement a class that contains an array member, so that any type of data can be stored in the array, and the value of a subscript in the array can also be returned according to the member method?
Thinking: it is not difficult to implement a class and the class contains an array member, so how to put any type of data into an array?
class Generic{ public int[] arr; public String[] arr1; public double[] arr2; } public class demo1 { public static void main(String[] args) { } }
From the above code, we can see that arrays arr, arr1 and arr2 can only store corresponding types of data, so how should we place different types of data in an array.
Idea: if the parent class of all classes is Object class, we can set the type to Object.
class Generic{ public Object[] arr; public Generic() { this.arr = new Object[10]; } public Object getArr(int pos){ return this.arr[pos]; } public void setArr(int pos,Object val){ this.arr[pos] = val; } } public class demo1 { public static void main(String[] args) { Generic generic = new Generic(); generic.setArr(0,1); generic.setArr(1,2); generic.setArr(2,"FHZ"); generic.setArr(3,3); int ret = (int)generic.getArr(1); System.out.println(ret); String ret1 = (String) generic.getArr(2); System.out.println(ret1); } }
The above code realizes the storage of different types in an array. In this code, I put forward two questions worth thinking about:
int ret = (int)generic.getArr(1);
String ret1 = (String) generic.getArr(2);
1. Why is forced type conversion required when receiving array subscript values?
Because generic Getarr (1) and generic The type of getarr (2) is Object, while RET and ret1 are int and String types respectively. Therefore, it needs to be transformed upward, so forced type conversion is required here.
2. Do we have to cast every time for a very complex array or when the length of the array is very large?
When the array is very large, it is really inconvenient for us to perform forced type conversion every time we print different types of data. Can we classify these different types of data? Of course, let's introduce the concept of genericity.
Therefore, the main purpose of generics is to specify what type of object the current container should hold. Let the compiler check. At this point, you need to pass the type as a parameter. You can pass in whatever type you need.
2.1 generic syntax
class Generic class<Type parameter list>{ } class Generic class<T1,T2,T3......Tn>{ }
The type parameter list has the following forms:
E stands for Element;
K means Key;
V represents Value;
N stands for Number;
T indicates Type;
S. U, V, etc. - second, third, fourth type.
The most commonly used are T and E.
Let me improve the above code with generics:
class Generic1<T>{ public T[] arr = (T[]) new Object[10]; public T getArr(int pos){ return this.arr[pos]; } public void setArr(int pos,T val){ this.arr[pos] = val; } } public class demo2 { public static void main(String[] args) { Generic1<Integer> generic = new Generic1<>(); generic.setArr(0,1); generic.setArr(1,2); generic.setArr(2,3); generic.setArr(3,4); Integer ret = generic.getArr(1); System.out.println(ret); Generic1<String> generic1 = new Generic1<>(); generic1.setArr(0,"FHF"); generic1.setArr(1,"FHZ"); generic1.setArr(2,"zhangsan"); String ret1 = generic1.getArr(2); System.out.println(ret1); } }
< T > after the class name is a placeholder, indicating that the current class is a generic class;
< integer > after Generic specifies the current type, that is, the array can only store integer arrays, and there is no need for forced type conversion when printing; The same is true for the following Generic < string >.
Using generics to store elements, the compiler will automatically filter for us when compiling.
2.2 instantiate a generic class
1.2 grammar
Class name<data type> Variable name = new Class name<data type>(); Generic1<Integer> generic = new Generic1<Integer>(); Generic1<String> generic1 = new Generic1<String>();
There are two points to note:
1. new Generic1<Integer>(); The integer here can not be written, as long as it is written in front;
2. The data type must be packaging type.
2.3 erasure mechanism
In the process of compiling, the code replaces all T with Object. This mechanism is called erasure mechanism.
2.4 upper bound of generics
When defining generic classes, we sometimes need to make certain constraints on the incoming type variables, which can be constrained by type boundaries.
2.4.1 grammar
class Generic class name<type parameter extends Type boundary>{ ... }
2.4.2 implementation of generic methods
Method qualifier <Type parameter list> Return value type method name(parameter list ) { ... }
3. Packaging
3.1 basic data type and its corresponding packaging type
Except that the wrapper classes corresponding to int and char are not capitalized, other types of wrapper classes are capitalized.
3.2 packing and unpacking
public static void main(String[] args) { int a = 20; Integer b = a; //Automatic packing, internal automatic call integer valueOf() Integer c = Integer.valueOf(a); // Manual packing System.out.println(b); System.out.println(c); System.out.println("===================="); Integer a1 = 30; int b1 = a1; // Automatic unpacking int c1 = a1.intValue(); // Manual unpacking System.out.println(b1); System.out.println(c1); }