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

  1. Code reuse

  1. Compile-time check type error

After using generics:

How to use generics

How to define

Generic classes, generic interfaces

Generic method

Use skills

  1. Type inference is automatically performed at instantiation time


  1. The original type


  1. 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>


  1. Qualified type parameters (generic erasure sets the type to a qualified type, such as the following is set to Number)

Multiple qualified


  1. 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

  1. A generic type with a primitive type cannot be instantiated
Pair<int.char> p = new Pair<>(8.'a');// Error compiling!
Copy the code
  1. Unable to create an instance of a type parameter
public class Test <T>{
    T t = new T();// Error compiling!
}
Copy the code
  1. A static field of type parameter cannot be declared
public class Test <T>{
    public static final T t;// Error compiling!
}
Copy the code
  1. Instanceof cannot be used with parameterized types

  1. Unable to create an array of parameterized types

  1. Generic classes cannot inherit Exception, Throwable, or catch Exception’s type parameters

  1. You cannot simultaneously define an overloaded method whose arguments become the same after two generic erasures
public class Example {
    // Set is used for both methods
	public void print(Set<String> strSet) {}public void print(Set<Integer> intSet) {}}Copy the code