1. Definition: The essence of generics is parameterized type, which is to parameterize the type from the original specific type. This type of parameter can be used in classes, interfaces and methods, which are called generic class, generic interface and generic method respectively.
2. Generic classes: The declaration of generic classes is similar to that of non-generic classes. In addition to adding type parameter declaration after the class name, the most typical container classes are List, Set and Map.
1 public class Box<T>{ 2 private T t; 3 4 public T getT() { 5 return t; 6 } 7 8 public void setT(T t) { 9 this.t = t; 10 } 11 }
a. Generic type parameters can only be reference type < Integer >, < Double > (including custom classes) and so on, not original type < int >, < double > etc.
b. When instantiating generic classes, the specific type of T must be specified.
c. Parametric type T can be written as arbitrary characters, and commonly used T, E, K, V are generic.
3. Generic interface: The definition and use of generic interface and generic class are basically the same.
1 public interface Box<T> { 2 public T next(); 3 }
A. When a class that implements a generic interface does not pass in a generic argument, it is necessary to add the generic declaration to the class when declaring such a class.
1 class B<T> implements Box<T>{ 2 @Override 3 public T next() { 4 return null; 5 } 6 }
b. When classes that implement generic interfaces are introduced into generic arguments, all places where generics are used need to be replaced by argument types.
1 public class B implements Box<String> { 2 3 private String[] fruits = new String[]{"Apple", "Banana", "Pear"}; 4 5 @Override 6 public String next() { 7 return null; 8 } 9 }
4. Generic methods: When calling methods, specify the specific types of generics;
1 // generic class 2 class Box<T> { 3 /** 4 * A generic method is declared in the generic class, using generic E, which can be of any type, the same type as T, or different. 5 * Because generic methods declare generics < E > when declared, the compiler can correctly identify generics recognized in generic methods even if generics are not declared in generic classes. 6 */ 7 public <E> void B_1(E t) { 8 System.out.println(t.toString()); 9 } 10 11 /** 12 * A generic method is declared in a generic class, using generic T. Note that this T is a completely new type and can not be the same type as the T declared in a generic class. 13 * 14 */ 15 public <T> void B_2(T t) { 16 System.out.println(t.toString()); 17 } 18 19 // Not a generic method 20 public void B_3(T t){ 21 System.out.println(t.toString()); 22 } 23 }
(a) All generic method declarations have a type parameter declaration section (separated by angle brackets) that precedes the method return type (in the examples above, <E>, <T>).
b. The generic method (B_1, B_2) is only the method that declares < T > and < E > and the member method that uses generic type in generic class is not the generic method (B_3).
c, < T > and < E > indicate that generic types T and E will be used in the method, and then generic types T and E can be used in the method.
d. The declaration of generic method body, like other methods, can only be a reference type, not a primitive type (int, double, char, etc.).
5. Upper and lower boundaries of generics: When using generics, we can also restrict the upper and lower boundaries of incoming generic type arguments, such as: type arguments are only allowed to pass in a certain type of parent class or a certain type of subclass; adding upper boundaries to generics, that is, the incoming type arguments must be subtypes of a specified type;
1 // generic class 2 class Box<T extends Number> { 3 private T t; 4 public Box(T t){ 5 this.t = t; 6 } 7 public T getT(){ 8 return t; 9 } 10 } 11 Box<Integer> b = new Box<Integer>(1000);// Integer Type is Number Subclasses of Types -- Correct 12 Box<String> s = new Box<String>("1000");// String Type is not Number Subclasses of Types -- Errors
6. Type wildcards: Usually used? Instead of specific type parameters,? Is a type argument, like Integer and Number, an actual type? It can be seen as the parent class of all types (List <?> logically, List < String >, List < Integer > and so on) of all List < specific type argument >.
1 public static void main(String[] args) { 2 Box b = new Box(); 3 List<String> sLst = new ArrayList<String>(); 4 sLst.add("100"); 5 List<Integer> iLst = new ArrayList<Integer>(); 6 iLst.add(100); 7 List<Number> nLst = new ArrayList<Number>(); 8 nLst.add(1000); 9 b.BPrint(sLst); 10 b.BPrint(iLst); 11 b.BPrint(nLst); 12 } 13 14 /** 15 * <? extends T>Indicates that the type represented by the wildcard is a subclass of type T 16 * <? super T>Represents that the type represented by this wildcard is the parent of type T 17 */ 18 class Box { 19 public void BPrint(List<?> lst) { 20 System.out.println(lst); 21 } 22 }