I. Self-summary
Generics specify the type of the variable you depend on, so that it is no longer a fixed type, but can be any type, and can be restricted to that type. List<Number> has no relation to List<Integer>; List<? Extends Number> is a List<? The parent of extends Integer>. Be aware of the effects of generic erasure.
Two, key words
Type parameters, type variables, type inference, primitive types, qualified type parameters, wildcards, type erasure, bridge methods
What are generics
A type parameter passed to a class, interface, or method (defines a type for the dependent class, which can be any type or a restricted type)
Why generics
- Code reuse
- Compile-time check type error
After using generics:
How to use generics
How to define
Generic classes, generic interfaces
Generic method
Use skills
- Type inference is automatically performed at instantiation time
- The original type
- Inheritance of generic classes (like interfaces)
The parent class:
There are three ways to inherit:
Note: Although Fruit is the parent of Apple, List<Fruit> has nothing to do with List<Apple>
- Qualified type parameters (generic erasure sets the type to a qualified type, such as the following is set to Number)
Multiple qualified
- The wildcard
Since List
and List
have no relationship, List
cannot be passed in as an argument when you set a method parameter to List
. In this case, you need wildcards and their inheritance relationships
Note: Clearly qualify the type <T extends Number> and the wildcard <? Extends Number>.
The qualified type is inTo define theDefine the range of dependent types;
And the wildcard is inWhen usingGives the range of type parameters passed in.
Wildcards and subtypes:
List
has nothing to do with List
even though Number is the parent of Integer
List<Integer> intList = new AraayList<>();
List<Number> numList = intList; // This is wrong!
// After the wildcard is used
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // This is ok! List
is
Copy the code
The following figure illustrates the inheritance relationship:
// the upper limit wildcard is passed in as a subclass of Number
// You can only retrieve data from the list, not store data. The compiler doesn't know what type you saved, but it will definitely return you the Number type.
private void process(List<? extends Number> list){/ * * * * /}
// The lower limit wildcard is passed in as the superclass of Number
// You can only store data in the list, not fetch data. The compiler knows that you are storing type Number, but it doesn't know what type to return to you.
private void process(List<? super Number> list){/ * * * * /}
// Infinite wildcards
private void process(List
list){/ * * * * /}
Copy the code
Why do we need infinite wildcards?
Naming rules for type parameters
- E-element (widely used by the Java Collections Framework)
- K – Key
- N – Number
- T – Type
- V – Value
- S,U,V etc. – 2nd, 3rd, 4th types
Type erasure
// Before erasing (no qualified type)
public class Box<T>{
private T t;
}
/ / erased
public class Box{
privateObject t; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -// before erasing (the first bound class will be taken if the parameter type is specified)
public class Box<T extends Comparable&Serializable>{
private T t;
}
/ / erased
public class Box<T extends Comparable&Serializable>{
private Comparable t;
}
Copy the code
For example:
Map<String, String> map = new HashMap<>();
map.put("a"."The first");
String s = map.get("a");// It looks like this: String = String;
//String s = (String)map.get("a");
// The compiler erases the generics to bring up the Object type, which helps us with strong casting
Copy the code
Bridge method:
Seven, use restrictions
- A generic type with a primitive type cannot be instantiated
Pair<int.char> p = new Pair<>(8.'a');// Error compiling!
Copy the code
- Unable to create an instance of a type parameter
public class Test <T>{
T t = new T();// Error compiling!
}
Copy the code
- A static field of type parameter cannot be declared
public class Test <T>{
public static final T t;// Error compiling!
}
Copy the code
- Instanceof cannot be used with parameterized types
- Unable to create an array of parameterized types
- Generic classes cannot inherit Exception, Throwable, or catch Exception’s type parameters
- You cannot simultaneously define an overloaded method whose arguments become the same after two generic erasures
public class Example {
// Set
public void print(Set<String> strSet) {}public void print(Set<Integer> intSet) {}}Copy the code