This is the 8th day of my participation in the August Text Challenge.More challenges in August
Unbounded wildcard
Is there a generic symbol that can refer to any type? , this is the unbounded wildcard
Unbounded wildcards: For unbounded types, any type can be passed in
The purpose of unbounded wildcards is to limit the range of types that generics can represent, from unbounded to bounded wildcards
A generic type is of type Object after type erasure, or any other specific type specified
However, there is also a point that such generics are not inheritable and are really limited to a type
Generic types, once identified, cannot be modified and do not participate in Java’s inheritance system
When a generic of a class is declared as Number, it can no longer receive subclasses of Number
The simple understanding is that generic types, once identified, are no longer inheritable
public class A<T> {
private T age;
}
Copy the code
public class B {
public void get(A<Number> age) {}}Copy the code
public class M {
public static void main(String[] args) {
B b = new B();
/ * * / correctly
A<Number> numberA = new A<>();
b.get(numberA);
/ * error * /
A<Integer> integerA = newA<>(); b.get(integerA); }}Copy the code
In the example above, the formal parameter is declared to be of type Number, but not compatible with its subclass Integer
Of course, the class A type Number, already identified by class B, can be declared generic again, but this is not compatibility under inheritance
In practice, you cannot use generics. Only generic classes can inherit the form of generic classes
That’s why unbounded wildcards, bounded wildcards exist
- Limits the scope in which generics can be declared
- Allows the declared concrete type to be added to the inheritance system
They can limit the scope of generics to parent and subclass inheritance
A bounded wildcard that limits the scope of upward and downward compatibility of the generic
Once unbounded wildcards are converted to bounded wildcards, they fall into two categories
- Upper limit specifies the wildcard
- Lower limit specifies the wildcard
Ceiling limit
Upper limit The keyword that qualifies a wildcard is extends
The syntax is
The upper bound means that the actual type and its subclasses can be accepted
Simply put, the actual type exists as the highest parent of the generic
Code sample
public class A<T> {
private T age;
}
Copy the code
public class B {
public void get(A<? extends Number> age) {}}Copy the code
public class M {
public static void main(String[] args) {
B b = new B();
/ * * / correctly
A<Number> numberA = new A<>();
b.get(numberA);
/ * * / correctly
A<Integer> integerA = newA<>(); b.get(integerA); }}Copy the code
Only class A generics in B type methods can be bounded
In this case, the upper limit of class A is Number, and it can accept Integer and Number parameters
Inheritance of generic types is achieved by specifying the scope of the generic representation, allowing downward compatibility with subclasses
The lower limit
The keyword of the lower limit wildcard is super
The syntax is
The lower limit means that the actual type and its parent can be received
Simply put, the actual type currently specified exists as the lowest subclass of the generic type
Code sample
public class A<T> {
private T age;
}
Copy the code
public class B {
public void get(A<? super Number> age) {}}Copy the code
public class M {
public static void main(String[] args) {
B b = new B();
/ * * / correctly
A<Number> numberA = new A<>();
b.get(numberA);
/ * error * /
A<Integer> integerA = newA<>(); b.get(integerA); }}Copy the code
You only need to limit the bounds of class A generics in B type methods
In this case, the lower limit of class A is Number, and Integer parameters cannot be accepted
It is worth noting:
- Generic classes can be capped
Public class name <T extends actual type > {}
- Generic classes cannot be lower bound
Public class name <T super actual type > {}
For bounded wildcards, you can use the generic notation instead. , but cannot be used as a lower limit, that is, a supertype wildcard