Reference: Java core technology
Before adding generics to java, the design of general programs is implemented by inheritance. Set the type parameters of methods to base classes. Such methods will have generality, such as the following
class ArrayList { private Object[] elementData; public Object get(int i) { } public void add(Object o) { } }
There are two problems in this implementation: ① when obtaining a value, you must cast it; ② you can add any Object object here without any error checking. Here we assume that StringValue is used to store the String collection. ArrayList only maintains an array of Object references. We cannot prevent the Integer type from being added to our String collection. When we need data, we need to convert the obtained Object object Object object to the type we expect. If we add unexpected types to the collection, there will be no errors during compilation But ClassCastException will be reported at runtime.
2, The benefits and essence of genericsBenefits of using generics
① Type safety
② Eliminate cast
The nature of generics
① Postpone the element type in the object / collection until the collection is created
② Type parameterization
Data type < generic parameter > object = new data type < generic parameter >;
ArrayList<String> list = new ArrayList<String>();
After jdk1.7, there is a type inference that generic types after new can be omitted
ArrayList<String> list = new ArrayList<>(); ArrayList<String> list = new ArrayList();
For type inference, just look to the left. for example
ArrayList list = new ArrayList<String>(); list.add(1); list.add("String");
There will be no errors here, and generic parameterization of String will not work here.
4, Generic classA generic class is a class with one or more type variables
Basic syntax: class name < generic identifier >
public class Pair<T> { T first; T second; Pair(T first , T second){ this.first = first; this.second = second; } public T getFirst() { return first; } public void setFirst(T first) { this.first = first; } public T getSecond() { return second; } public void setSecond(T second) { this.second = second; } }5, Generic interface
The use of generic interfaces is basically the same as that of generic classes
interface GenericType<T> { T T; //Error }
In the interface, all instance domains are initialized to public static final
All methods are public
Therefore, generic variables are not allowed in the above instance, because all variables in the interface are immutable.
public static <T> T getMiddle(T[] t) { return t[t.length /2]; }
When using, parameterize the type
String[] str = {"A" , "B" ,"C"}; String middle = Generic.<String>getMiddle(str);7, Generic wildcard?
1.? Unbounded wildcards
-
Why? Unbounded wildcards
Example: there is a parent class Animal and several children classes, such as dog, cat, etc. now I need a list of animals. The initial idea is:
List<Animal> listAnimals
But the right idea:
List<? extends Animal> listAnimals
Wildcards don't really make sense when declaring local variables, but when you declare a parameter for a method, it's very important.
package cn.ArrayList; import java.util.ArrayList; import java.util.List; /** * @author Four or five and ten * @create 2020/2/13 20:17 */ public class demo2 { static int countLegs (List<? extends Animal > animals ) { int retVal = 0; for ( Animal animal : animals ){ } return retVal; } static int countLegs1 (List< Animal > animals ){ int retVal = 0; for ( Animal animal : animals ){ } return retVal; } public static void main(String[] args) { List<Dog> dogs = new ArrayList<>(); // No mistake. countLegs( dogs ); // Report errors countLegs1(dogs); } } class Animal{ } class Dog extends Animal{ }
Error message: Error:(32, 20) java: incompatible type: Java. Util. List < CN. ArrayList. Dog > cannot be converted to Java. Util. List < CN. ArrayList. Animal >
? Difference from T:
? Both T and t represent uncertain types. The difference is that we can operate on T, but we can operate on t? No way
In other words, the generic wildcard is meaningful in methods. T is a certain type, which is usually used for the definition of generic classes and methods,? Is an indefinite type, usually used for calling code and parameters of generic methods, not for defining classes and generic methods.
2.< ? extends E>
-
Concept: < extension E > is an upper bound wildcard. It is declared with the extensions keyword to indicate that the parameterized type may be the specified type or a subclass of this type.
There are two benefits to doing so:
- Compilation is unsuccessful if the type passed in is not a subclass of E or e
- You can use the method of E in generics, otherwise you have to convert it to e to use it
- Compilation is unsuccessful if the type passed in is not a subclass of E or e
3.< ? super E>
-
Concept:
< super E > is the lower bound wildcard indicating that the parameterized type may be the specified type, or the parent type of this type until the Object
There is no generic type object on the virtual machine -- all objects belong to ordinary classes
1. Type erasure
Whenever a generic type is defined, a corresponding primitive type is automatically provided. The name of the original type is the generic type name after the type parameter is deleted. Erase the type variable and replace it with a qualified type (infinite type uses Object). For example, the original type of the Pair generic class above
public class Pair { Object first; Object second; Pair(Object first , Object second){ this.first = first; this.second = second; } public Object getFirst() { return first; } public void setFirst(Object first) { this.first = first; } public Object getSecond() { return second; } public void setSecond(Object second) { this.second = second; } }
2. Translation of generic expressions and generic methods
When a program calls a generic method, the compiler inserts a cast if it erases the return type.
Pair<Employee> buddies = ... Employee boddy = buddies.getFirst();
After erasing the return type of getFirst(), the compiler will automatically insert a cast for Employee. In other words, the compiler translates the call of this method into two virtual machine instructions:
(1) Call to the original method Pair.getFirst()
(2) Cast the returned Object type to Employee type
In summary, you need to know about java generic Transformation:
① There are no generics on the virtual machine, only ordinary classes and methods
② All type parameters are replaced with their qualified types
The bridge method is synthesized to maintain polymorphism
Insert cast if necessary to maintain type security