reference

Preface:

Java Generics is a new feature introduced in JDK 5. Generics provide compile-time type-safety checks that allow developers to detect illegal types at compile time.

The nature of generics is parameterized typing, which means that the data type being operated on is specified as a parameter.

Benefits of generics

public class GlmapperGeneric<T> {
		private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }
  
    public static void main(String[] args) {
        // doNothing} /** * public void */noSpecifyType(){
    GlmapperGeneric glmapperGeneric = new GlmapperGeneric();
    glmapperGeneric.set("test"); // The cast String is requiredtest = (String) glmapperGeneric.get();
    System.out.println(test); } /** * specifies the type */ public voidspecifyType(){
    GlmapperGeneric<String> glmapperGeneric = new GlmapperGeneric();
    glmapperGeneric.set("test"); // There is no need to cast Stringtest = glmapperGeneric.get();
    System.out.println(test); }}Copy the code

SpecifyType methods in this code omit casting to check type safety at compile time and can be used on classes, methods, and interfaces.

#### wildcard in the generic

When we define generic classes, generic methods, and generic interfaces, we often encounter different wildcards, such as T, E, K, V, and so on. What do these wildcards mean?

The usual T, E, K, V? Essentially, these are wildcards, no difference, just code conventions. For example, in the above code, T can be replaced with any letter between A and Z without affecting the normal operation of the program. However, if T is replaced with other letters, the readability may be weaker. In general, T, E, K, V, right? Here’s the deal:

  • ? Represents an indeterminate Java type
  • T (type) indicates a specific Java type
  • K and V are key values in Java key values
  • E stands for Element

# # # # #? Unbounded wildcard

static int countLegs (List<? extends Animal > animals ) {
    int retVal = 0;
    for ( Animal animal : animals )
    {
        retVal += animal.countLegs();
    }
    return retVal;
}

static int countLegs1 (List< Animal > animals ){
    int retVal = 0;
    for ( Animal animal : animals )
    {
        retVal += animal.countLegs();
    }
    returnretVal; } public static void main(String[] args) { List<Dog> dogs = new ArrayList<>(); CountLegs (dogs); / / error countLegs1 (dogs); }Copy the code

When countLegs1 is called, it flutters red with the following error message:

So you can use unrestricted wildcards (a question mark in Angle brackets, <? >), indicating that any type can be held. As in countLegs, the last class is qualified, but it doesn’t care what type it is, so all subclasses of Animal passed in can be supported without an error. CountLegs1 doesn’t.

# # # # # Class and Class <? > the difference between

When Class is instantiated, T is replaced by a concrete Class. Class<? > < span style = “box-sizing: border-box! Important; Can represent any type, so it is mainly used for declarative restrictions. For example, we can declare this:

Public Class<? > clazz; Public Class<T> clazzT;Copy the code

So if you also want to public Class clazzT; In this case, the current class must also specify T

public class Test3<T> { public Class<? > clazz; Public Class<T> clazzT; }Copy the code