generic paradigm
1. Definition
The collection container class cannot determine what type of objects actually exist in this container in the design stage and declaration stage, so in jdk1 Before 5, the element type can only be designed as Object, jdk1 After 5, use generics to solve it. At this time, except that the type of the element is uncertain, other parts are determined, such as how to save and manage the element. Therefore, the type of the element is designed as a parameter, which is called genericity. Colletion, List, E is the type parameter, that is, generic type.
2. Concept
The so-called genericity allows you to represent the type of an attribute in a class or the return value and parameter type of a method through an identifier when defining a class or interface. This type parameter will be determined when used (for example, inherit or implement this interface; when declaring variables and creating objects with this type).
3. Parametric type
JDK1. The concept introduced after 5 allows us to specify the type of collection elements when creating collection objects, such as List, and use List when instantiating collection objects.
4. Use example
-
Use generics in Collections
- Set of interfaces and classes in jd5.0 0 is modified to a structure with generics;
- When instantiating a collection class, you can specify a specific generic type;
- After specifying the generic type, in the set class and set interface, when defining the class and interface, the location where the generic type of the class is used by the internal structure (method, constructor, attribute, etc.) needs to be specified as the instantiated generic type;
- The type of a generic type must be a class, not a basic data type. You need to use the location of the basic data type to wrap the class.
- If the generic type is not specified during instantiation, the default type is Java Lang. object type. This is not recommended, so the type of generic type should be specified when instantiating.
-
How to customize generic structures
-
Custom generic classes, generic interfaces
Generic classes cannot be static because static classes are initialized before class instantiation. At this time, the generic type is uncertain and initialization fails.
/** * Custom generic class * * @param <T> When customizing, you can treat generics as a concrete class, which is easy to understand */ public class Person<T> { private String sex; private Integer age; //The internal structure of a class can use the generics of the class (properties, methods, parameters, etc.) private T personT; public Person() { } public Person(String sex, Integer age, T personT) { this.sex = sex; this.age = age; this.personT = personT; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public T getPersonT() { return personT; } public void setPersonT(T personT) { this.personT = personT; } @Override public String toString() { return "Person{" + "sex='" + sex + '\'' + ", age=" + age + ", personT=" + personT + '}'; } }
/** * Generic subclass * When inheriting a generic parent class, the parent class specifies a generic type. When instantiating a subclass, you don't have to specify a generic type. */ public class man extends Person<Integer> { }
/** * Generic subclass * When inheriting a generic parent class, the parent class does not specify a generic type. When instantiating a subclass, you need to specify a generic type. */ public class woman<T> extends Person<T> { }
-
Custom generic method
Generic method definition: a generic structure appears in the method. Note: the generic parameters of a method have nothing to do with the generic parameters of a class.
// Custom generic method public <E> List<E> copyFromArrayToList(E[] arr) { List<E> list = new ArrayList<>(); for (E e : list) { list.add(e); } return list; }
How to understand the return value of a method? A new value is added in front of the List?
A: tell the compiler that E is a generic type, not a parameter type class. If the generic method is not added before, the compiler will think that E is a parameter type class and will look for this class. At this time, it cannot be found, so the compiler will prompt an error.
// Bad generic method writing (no generics are added before the return value) public List<E> copyFromArrayToList(E[] arr) { List<E> list = new ArrayList<>(); for (E e : list) { list.add(e); } return list; }
Static generic methods: generic parameters are determined when the method is called, not when the class is instantiated, so there can be static generic methods.
/** * Static generic method */ public static <E> List<E> copyFromArrayToList2(E[] arr) { List<E> list = new ArrayList<>(); for (E e : list) { list.add(e); } return list; }
-
5. Wildcards?
- A and B are parent-child relationships, so g <'a '> and G <'b' > are parallel relationships, non parent-child relationships, G <? > Is their root parent
/** * Wildcards? Examples of use in Collections * List<?>It is the parent class of list < Object > and list < string >, while list < Object > and list < string > are in parallel relationship, not parent-child relationship * Conclusion: A and B are parent-child relationship, G < a > and G < b > are parallel relationship, non parent-child relationship, G <? > Is their root parent */ public static void main(String[] args) { List<Object> list1 = new ArrayList<>(Arrays.asList(1, 2, 3)); List<String> list2 = new ArrayList<>(Arrays.asList("a", "b", "c")); List<?> list = new ArrayList<>(Arrays.asList(1, 2, 3)); print(list1); print(list2); print(list); } private static void print(List<?> list) { Iterator<?> iterator = list.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println(obj); } }
-
G<?> Operation of collection (collection object using wildcards) data
- Read data operation, the return value is Java Lang. Object, because Object is the parent class of all classes;
- Add data operation, cannot add data to G <? > When adding data to the collection, you can only read data except adding null objects.
-
Use of restricted wildcards
/** * Use of restricted wildcards * When wildcard is used as subclass inheritance, the type occupied by wildcard must be a subclass of Animal, including Animal * When wildcard is used as superclass, the type of wildcard placeholder must be the parent class of Animal, including Animal */ public static void main(String[] args) { List<? extends Animal> list1 = null; List<? super Animal> list2 = null; List<Dog> list3 = new ArrayList<>(); List<Animal> list4 = new ArrayList<>(); List<Object> list5 = new ArrayList<>(); list1 = list3; list1 = list4; //list1 = list5;// An error is reported and cannot be assigned because Object is the parent class of Animal //list2 = list3;// An error is reported and cannot be assigned because Dog is a subclass of Animal list2 = list4; list2 = list5; /** * Value operation */ //When the wildcard is used for subclass inheritance, the return value after the collection value is taken cannot be lower than (< =) the parent class Animal animal = list1.get(0); Object obj = list1.get(0); //When a wildcard is used as a superclass, the return value must be higher than that of the parent class (>) Object object = list2.get(0); /** * Fill value operation */ //list1.add(new Object());// An error is reported and cannot be filled //list1.add(new Animal());// An error is reported and cannot be filled //list1.add(new Dog());// An error is reported and cannot be filled //list2.add(new Object());// An error is reported and cannot be filled list2.add(new Animal()); list2.add(new Dog()); }