JDK1.5. Add a Generic type, that is, the type parameter Generic
The so-called genericity is to allow an identifier to represent the type of an attribute in a class or the return value and parameter type of a method when defining a class or interface
This type parameter will be determined when used (declaring variables, creating objects, and calling methods (generic methods) with this type) (i.e., passing in actual type parameters, also known as type arguments)
Why generics
Isn't it possible to store data directly with Object
1. Solve the security problem of element storage, such as commodity and drug labels, without making mistakes
2. Solve the problem of type cast when obtaining data elements
Generic advantages
It can detect errors at compile time rather than at run time to increase readability and stability
Naming conventions single character uppercase, e.g. E T K V
Use of generics
Generic class, generic interface; generic method
- T can only be "class" and cannot be filled with basic data type, but can be filled with wrapper class
- The constructor of the generic class is as follows: public GenericClass() {}
- Different generic references cannot be assigned to each other. Although ArrayList and ArrayList are two types at compile time, only one ArrayList is loaded into the JVM at run time
ArrayList list1 = null, ArrayList List2 = list1; // FALSE - If a generic type is not specified, the type corresponding to the generic type is treated as Object, but it is not equivalent to Object
Experience: generics can be used all the way or not all the way
// Do not use generics public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("a"); list.add(new Date());// Strong conversion to ClassCastException test(list);// Generic erasure, compilation does not check } public static void test(ArrayList<String> list) { for (String s : list) { System.out.println(s); } } // <Object> public static void main(String[] args) { ArrayList<Object> list = new ArrayList<>(); list.add("a"); list.add(new Date()); test(list);// Once the Object class is specified, the compilation will type check. There is an error in compilation here } public static void test(ArrayList<String> list) { for (String s : list) { System.out.println(s); } }
Static methods use generics
public class Order<E> { String orderName; int orderId; E orderE; public Order() { // Cannot directly new E [] E[] a = (E[])new Object[10]; } public Order(String orderName, int orderId, E orderE) { this.orderName = orderName; this.orderId = orderId; this.orderE = orderE; } // Generic methods can be static. Generic parameters are determined when calling methods, not when instantiating classes, public static <T> List<T> copy(T[] arr){ ArrayList<T> list = new ArrayList<>(); for(T t : arr) list.add(t); return list; } // Class generics cannot be used in static methods. Static structure loading is earlier than object creation /*public static void show(E orderE){ // Compilation error System.out.println(orderE); }*/ }
Exception cannot be generic
public class MyException extends Exception {} / / error
try{
} catch(T t){
}Compilation failed
Generic class
public class B extends A<String> { public static void main(String[] args) { B b = new B(); b.setName("a"); String name = b.getName(); System.out.println(name); // a A<Integer> a = new A<>(); a.setName(1); Integer name1 = a.getName(); System.out.println(name1);// 1 } } public class A<E> { private E name; private int age; get method set method }
class Father<T1, T2> { } class Son1<A,B> extends Father { // The data type of the parent class is Object } class Son2<A,B> extends Father<Integer, String> { // The data type of the parent class is Integer, String } class Son3<T1, T2, A, B> extends Father<T1, T2> { // What types are the subclasses T1 and T2? What types are the parent classes T1 and T2 } class Son4<T2, A, B> extends Father<Integer, T2> { // What type is the child class T2? What type is the parent class T2 }
Usage scenarios for generic classes
Universal CRUD
public class DAO<T>{ // Add, delete, modify and query public void add(T t){ ... } ... } public class Customer { private String name; } public class CustomerDAO extends DAO<Customer> { // DAO is a general method of operating database } public class EmpDAO extends DAO<Emp> { } public class Test{ public static void main(String[] args) { CustomerDAO dao = new CustomerDAO(); dao.add(new Customer("tom")); } }
generic interface
Similar to generic classes
...
generic method
Method return value preceded by < T >, or static < T >
public class Test{ public static void main(String[] args) { Test test = new Test(); Integer[] arr = new Integer[]{1, 2, 3}; List<Integer> list = test.copyFromArrayToList(arr); } // This method is generic // When the method is called, E is determined public <E> List<E> copyFromArrayToList(E[] arr) { ArrayList<E> lsit = new ArrayList<>(); for(E e : arr) { list.add(e); } return list; } }
Attention
Embodiment in inheritance
Object obj = null; String str = null; obj = str; Object[] arr1 = null; String[] arr2 = null; arr1 = arr2; List<Object> list1 = null; List<String> lsit2 = null; // list1 and list2 have no child parent relationship at this time // list1 = list2; error // Class A is the parent of class B, but g < a > and G < b > have no child parent relationship // Class A is the parent of class B, but a < g > has a child parent relationship with B < g >
Collection< Object >,Collection,Collection< String>
/* Compare the three differences: printCollection(Collection c) printCollection(Collection<Object> c) printCollection(Collection<String> c) */ public class T { public static void main(String[] args) { // I: List list = new ArrayList();//You can call methods 1 and 2, and calling 3 will force an error list.add("A"); list.add(1); printCollection(list); // II: List<String> list = new ArrayList<>(); //You can call 1,3 to call 2. Compilation error list.add("A"); list.add("Aa"); printCollection(list); } // 1 // public static void printCollection(Collection c) { // Iterator i = c.iterator(); // for (int k = 0; k < c.size(); k++) { // System.out.println(i.next()); // } // } // 2 public static void printCollection(Collection<Object> c) { for (Object e : c) { System.out.println(e); } } // 3 // public static void printCollection(Collection<String> c) { // for (String e : c) { // System.out.println(e); // } // } Note: 1, 2, 3 Cannot exist at the same time, compilation will make an error }
wildcard
Wildcard use? express
be careful
Cannot be used on generic method declarations. Public static <? > void test(ArrayList list){ }
Cannot be used on declaration of generic class class generictypeclass <? > { }
Cannot be used to create an object ArrayList <? > list2 = new ArrayList <?> ();
unlimited
// It is similar to equals (Object obj) public void print(List<?> list){ Iterator<?> iterator = list.iterator(); while(iterator.hasNext()){ Object obj = iterator.next(); System.out.println(obj); } } // If there is no wildcard, write many traversal methods public void print1(List<String> list){ Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } } public void print2(List<Integer> list){ Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } }
upper bound
<? extends Person> public static void printCollection3(Collection<? extends Person> coll) { Iterator<?> iterator = coll.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } // Because it can only be Person or a subclass of Person
Lower bound
<? super Person> public static void printCollection4(Collection<? super Person> coll) { Iterator<?> iterator = coll.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } // Because it can only be Person or the parent class of Person