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

  1. Limits the scope in which generics can be declared
  2. 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 cappedPublic class name <T extends actual type > {}
  • Generic classes cannot be lower boundPublic 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