This paper introduces the concept, principle and use of generics in Java in detail, such as upper and lower generics, generics wildcards, etc.
1 the generic
Necessity of birth: Java1.4 or earlier, the List collection can hold any type, and it is easy to raise a ClassCastException when operating uniformly on the elements in the collection. When there are various data types, it is not easy to operate uniformly on the elements of a collection.
Like an array, only one type of data can be stored.
A new technology has been added in JDK1.5: generics.
1.1 define
Generics, or parameterized types. As the name implies, a type is parameterized from an original concrete type, similar to a variable parameter in a method. In this case, the type is also defined as a parameter (called a type variable), and then passed in the concrete type (type argument) when the/is used. This type variable can be used in the creation of classes, interfaces, and methods. And of course the most common is in collections.
Set syntax: class name < type variable >, also called parameterized type.
Type variables: use uppercase and can only be reference types, not base data types. In Java, the variable E represents the element type of the collection, K and V represent the key and value types of the table respectively, and T represents “any type”.
A generic type can be instantiated by replacing a type variable with a concrete type.
1.2 role
- Moving run-time exceptions forward to classcastExceptions facilitates unified operation of elements and optimizes program structure.
- The generic parameter, once specified, specifies that only one data type can be stored when the class is used. At this time, the collection can also remember the type of the elements in the collection, so there is no need to cast the collection elements, making the program more concise.
1.3 a generic class
Define generics on classes. Public class name < generic type 1,… >
Note: Generic types must be reference types.
case
Declare an indeterminate type (type variable) on a class; The indeterminate type can be used in either class.
public class Genericity<T> { private T obj; public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; }}Copy the code
Use generic classes
Genericity<String> tool = new Genericity<String>(); // Initialize T with String. tool.setObj("ggg");Copy the code
1.4 Generic methods
Generics can be defined in terms of methods: generic methods. The generic declaration precedes the return value of the method, and can be inconsistent with the generic declaration on the class name!
Class ss<Q> {public <T> void set(T T) {} public <T> void set(T T) {} public <T> void set(T T) {} Public Q getXxx(Q Q) {return Q; }}Copy the code
Note:
When a generic is declared after the class name. If you want to use the same generic variables in a static method of the class, you still have to redeclare the method before returning it, even if you have already declared a generic on the class. But non-static methods can use generic variables of the same name without having to declare them again! Examples are as follows:
Public class GenericDemo01<T> {// GenericDemo01<T> {// GenericDemo01<T> {// GenericDemo01<T> {// GenericDemo01<T> {// GenericDemo01<T> {// GenericDemo01<T> {// Public void get1(T T) {// Return T get2() { return null; } public static <T> void get3(T T) {} public static <T> void get3(T T) {} Public static <T> T get4() {return null; public static <T> T get4() {return null; }}Copy the code
Usage details:
List list=New ArrayList();
List list=New ArrayList();
List list=New ArrayList(); // Generic inference.JDK1.7
All three of these are fine. However, the declared generic types must be the same. Generics can only store reference types. After JDK1.5, it is recommended to use generics, otherwise you will be warned.
1.5 Generic interfaces
1.5.1 Definition of generic Interfaces
Demand: Add, delete, modify and check students:
Interface StudentDao{// Add: void add(Student stu); // delete: Boolean delete(String id); // Modify: Boolean update(Student stu); Student findById(String id); }Copy the code
Set a concrete implementation class: to implement the methods in the interface, then need to set a set of interfaces for an object, and set a set of implementation classes:
Teacher: Set up a set of interface, set up a set of implementation class:
This is more cumbersome, so you can use generic interfaces.
1.5.1 Use of generics on interfaces
Using generic interfaces reduces the number of Dao interface designs.
interface Dao<T>{ void add(T t); // Add Boolean delete(String id); // delete Boolean update(T T); T findById(String id); }Copy the code
1.6 Generic wildcards and upper and lower generics
Collection<? >? : can represent any type
Collection<? > c5 = new ArrayList<Object>(); Collection<? > c6 = new ArrayList<Animal>(); Collection<? > c7 = new ArrayList<Dog>(); Collection<? > c8 = new ArrayList<Cat>();Copy the code
1.6.1 Upper bound generics
Collection<? extends E> ? Only E or a subclass of E: such generics are called restricted generics: upper bound generics.
Generally, upper limits are used when storing elements. Extends E). Because once the type is determined, all the deposits are E or subclasses of E, and all the withdrawals are calculated according to the upper type E, so there is no type safety hazard
Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();
Copy the code
1.6.1 Lower-limit generics
Comparator<? super E> ? Can only be type E or a parent of type E (or compile an error) : the lower limit of a restricted generic. (Generally only used for comparators)
//min comparator min(Collection<? extends T> coll, Comparator<? Super T> comp) //sort sort Comparator sort(List<T> List, Comparator<? super T> c) Collection<? super Animal> c13 = new ArrayList<Object>(); Collection<? super Animal> c14 = new ArrayList<Animal>(); Collection<? super Animal> c15 = new ArrayList<Dog>(); Collection<? super Animal> c16 = new ArrayList<Cat>();Copy the code
1.7 Generic erasure
Generics in Java are basically implemented at the compiler level. The type information in the generics is not contained in the generated Java bytecode. Type parameters added when using generics are removed by the compiler at compile time. This process is called type erasure. Types such as List and List defined in code become lists when compiled. All the JVM sees is the List, and the type information added by generics is invisible to the JVM. The goal is to ensure compatibility with the binary libraries developed prior to Java 5.
The basic process of type erasure is also relatively simple, starting with finding the concrete class to replace type parameters. This concrete class is usually Object. If an upper bound is specified for a type parameter, this upper bound is used. Replace all the type arguments in your code with concrete classes.
ArrayList<String> list1 = new ArrayList<String>(); list1.add("abc"); ArrayList<Integer> list2 = new ArrayList<Integer>(); list2.add(123); Println (list1.getClass() == list2.getClass()); // Will return true system.out.println (list1.getClass() == list2.getClass());Copy the code