“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

I’ve been writing Java code for a while, but I’ve been giving up on generics whenever I see them. However, I found that generics are used in many places in the company’s code today, so today I will sort out what I understand about generics.

What is a generic

Generic Programming is a style or paradigm of a programming language. Generics allow programmers to write code in a strongly typed programming language with types that are specified later, and to specify these types as arguments during instantiation. There are mainly two definitions of generics: 1 ️ Some types containing type parameters in program encoding, that is to say, parameters of generics can only represent classes but cannot represent individual objects. 2 ️ Some classes containing parameters in the program code. Its arguments can represent classes or objects, and so on.

The explanation above 👆 comes from Baidu Encyclopedia. Simply speaking, generics is a code paradigm.

Java generics

Arguments to Java generics can only represent classes, not individual objects. Because the actual types of Java generics’ type parameters are eliminated at compile time, there is no way to know the types of their type parameters at run time, and there is no way to directly use base value types as generic type parameters.

Java Generics Design Principles:

Defer typing until you create an object or call a method to specify a particular type. As long as there are no warnings at compile time, there will be no ClasscastExceptions at run time.

Here’s a simple generic example:

public class Generic {

    public static void main(String[] args) {
        // C can accept strings
        C<String> stringC = new C<>("Hello world");
        System.out.println(stringC);
        
        // C can accept integers
        C<Integer> integerC = new C<>(100); System.out.println(integerC); }}// C can accept any type of initialization
class C<T> {
    private T item;

    public C(T t){
        item = t;
    }

    @Override
    public String toString(a) {
        return  item + ""; }}Copy the code

T, E, K, V

T, E, K, and V are essentially wildcards. Coding is sometimes a formality. For example, we can use any letter between A and Z to represent the wildcard, without affecting the normal operation of the program. In general, T, E, K, and V are agreed as follows:

  • ?Represents an indeterminate Java type
  • T ( type )Represents a specific Java type
  • K V ( key value )Each represents the Key Value in Java Key values
  • E ( element )On behalf of the Element

The wildcard

  • Upper bound wildcard? extends T

    For example the List
    is to accept data types such as List

    or List

    .

  • Lower bound wildcard? super T

    For example the List
    is to make up for the fact that only one type of data can be stored.

public class Generic {

    public static void main(String[] args) {
        / / can
        List<? super Number> list = new ArrayList<>();
        list.add(10);
        list.add(20L);
        list.add(20.2);

        System.out.println(list);

        List<Integer> list1 = new ArrayList<>();
        List<Long> list2 = new ArrayList<>();

        list1.add(10);
        list1.add(20);

        list2.add(10L);
        list2.add(20L);

        read(list1);
        read(list2);
    }

    private static void read(List< ? extends Number> list) {
        Number first = list.get(0);
        Number last = list.get(list.size() - 1);
        System.out.println("first = " + first.toString() + " last = "+ last.toString()); }}Copy the code

Finally, take a look at the PECS (Producer Extends Consumer Super) principle:

  • The upper bound Extends is appropriate for reading content out frequently
  • If it’s always inserted, it’s good to use the lower Super

Generic case

// Multiparameter generics
class Person<N.A.S> {

    private N name;
    private A age;
    private S sex;

    Person(N name, A age, S sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public N getName(a) {
        return name;
    }
    public void setName(N name) {
        this.name = name;
    }
    public A getAge(a) {
        return age;
    }
    public void setAge(A age) {
        this.age = age;
    }
    public S getSex(a) {
        return sex;
    }
    public void setSex(S sex) {
        this.sex = sex;
    }

    @Override
    public String toString(a) {
        return "Name:" + name + ",年龄:" + age + ", gender:+ sex; }}/ / use
public class Generic {

    public static void main(String[] args) {

        Person<String, Integer, Character> person = new Person<String, Integer, Character>("Egg fried rice.".28.'male');
        printPerson(person);
        // Name: egg fried rice; Age: 28; Gender: male
    }
    
    // Generic methods
    private static <T> void printPerson(T person){
        if( person ! =null) { System.out.println(person); }}}Copy the code