[Java generic] generic usage (generic class usage | generic method usage | generic wildcard| Generic security check)

Keywords: Java





1, Generic class usage


Generic class usage: declare the generic type before use. If the generic type is not declared, it means that the generic type of this class is Object type;


Generic class code:

public class Student<T> {

    private String name;
    private int age;
    /**
     * The data type is unknown
     *  Using a generic representation, the runtime determines the type
     */
    private T data;

    public Student(String name, int age, T data) {
        this.name = name;
        this.age = age;
        this.data = data;
    }
}

Indicate generic type: Specifies that the generic type of the generic class is String type, so the location where T type is used in this class must be String type. The generic declaration of the generic class must be declared after the class name when used;

        // Specifies that the generic type of the generic class is a String type
        //      In this class, where T type is used, it must be String type
        //      The generic declaration of a generic class, which is declared after the class name when used
        Student<String> student = new Student("Tom", 16, "Cat");
        String data = student.getData();

Do not specify generic type: if the generic type is not specified, the generic type defaults to Object type; As shown in the following example, the obtained generic type variable is also Object type and needs to be forcibly converted to String type;

        // If the generic type is not specified
        //      The generic type defaults to Object type
        Student student1 = new Student("Tom", 16, "Cat");
        // The obtained generic type variable is also an Object type and needs to be forcibly converted to String
        String data1 = (String) student1.getData();




2, Generic method usage


Generic method: pass String as parameter to the following generic method, and the type of T in the generic method is String type;

    public <T, A> T getData2(T arg){
        T data = arg;
        return data;
    }

Specify generic method: specify the generic class of the generic method, the generic declaration of the generic method, and the declaration in front of the method name when calling; This usage is rare;

        // Specifies the generic class of the generic method
        //      Generic declaration of a generic method, declared before the method name when called
        student.<String, Integer>getData2("Mouse");

Do not specify generic methods: generic types can also not be declared in generic methods. The passed in parameters are generic T types. If String is set for the passed in parameters, the generic T is implicitly set to String type;

        // Generic types can also not be declared in generic methods
        //      The parameter passed in is a generic T type
        //      If String is set for the incoming parameter, the generic T is implicitly set to String type
        String data2 = student.getData2("Mouse");




3, Generic wildcard <? >


If the current generic type is uncertain, use? As a wildcard, this usage is the same as specifying a generic type as an Object type;

? Examples of wildcard usage:

        // Use <? > Wildcards as generics
        //      The generic type is specified as the Object type by default
        Student<?> student2 = new Student("Tom", 16, "Cat");
        String data2 = (String) student1.getData();

above? Wildcard usage is equivalent to the following usage without specifying generics:

        // If the generic type is not specified
        //      The generic type defaults to Object type
        Student student1 = new Student("Tom", 16, "Cat");
        // The obtained generic type variable is also an Object type and needs to be forcibly converted to String
        String data1 = (String) student1.getData();




4, Generic security check


Notice below 2 2 For the usage of 2 generic types, the first method is recommended;

        // Generic security check
        // Recommended writing
        Student<String> student3 = new Student<>("Tom", 16, "Cat");
        // Not recommended
        Student student4 = new Student<String>("Tom", 16, "Cat");

Creating objects with the new keyword occurs at runtime, that is, the new student < string > ("Tom", 16, "cat") code is executed at runtime, which simply does not play the role of compile time security check. In terms of security check, this writing has no meaning;


Take the List generic as an example:

  • Example of security check during compilation:
        // The compiler checks at compile time
        List<String> list1 = new ArrayList<>();
        list1.add(1);

The following errors will be reported;

  • No security check at compile time example:
        // The compiler does not check at compile time
        List list2 = new ArrayList<String>();
        list2.add(1);

There is no error in this code;





5, Complete code example



1. Generic class / method


/**
 * Generic class
 *  This T type is used as a parameter
 *  T Is a parameterized type that can be passed in externally
 *
 * @param <T>
 */
public class Student<T> {

    private String name;
    private int age;
    /**
     * The data type is unknown
     *  Using a generic representation, the runtime determines the type
     */
    private T data;

    public Student(String name, int age, T data) {
        this.name = name;
        this.age = age;
        this.data = data;
    }

    /**
     * The method is not generic
     *  This method is a normal method, and the return value type is T type
     * @return
     */
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    /**
     * Generic method is to pass a type as a parameter
     *      Method specifies a generic type, which is written as follows:;
     *
     * The method is generic
     *      Method specifies 2 generics
     *      Number of generics. There can be many generics
     *      Multiple generics are separated by commas
     *
     * The generic T specified by the generic method has nothing to do with the generic T in the class
     *      The two T's can be of different types
     *
     * Generic T defined in generic method
     *      T with parameter type
     *      T of return value type
     *      Method internal T
     *      All of the same type
     *
     * It has nothing to do with T in generic classes
     *
     * @param <T>
     * @param <A>
     * @return
     */
    public <T, A> T getData2(T arg){
        T data = arg;
        return data;
    }

    public <T> T getData4(T arg){
        T data = arg;
        return data;
    }

    /**
     * If you use generics in a class in a static method
     *      This use is wrong
     *
     * If you must use generic T in static methods
     *      Then the generic T must be a generic of a static method
     *      Cannot be a generic type of a class
     *
     * @param arg
     * @return
     */
    public static <T> T getData3(T arg){
        T data = arg;
        return data;
    }
}

2. main function


import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Specifies that the generic type of the generic class is a String type
        //      In this class, where T type is used, it must be String type
        //      The generic declaration of a generic class, which is declared after the class name when used
        Student<String> student = new Student("Tom", 16, "Cat");
        String data = student.getData();


        // If the generic type is not specified
        //      The generic type defaults to Object type
        Student student1 = new Student("Tom", 16, "Cat");
        // The obtained generic type variable is also an Object type and needs to be forcibly converted to String
        String data1 = (String) student1.getData();

        // Use <? > Wildcards as generics
        //      The generic type is specified as the Object type by default
        Student<?> student2 = new Student("Tom", 16, "Cat");
        String data2 = (String) student1.getData();

        // Generic security check
        // Recommended writing
        Student<String> student3 = new Student<>("Tom", 16, "Cat");
        // Not recommended
        Student student4 = new Student<String>("Tom", 16, "Cat");

        // Specifies the generic class of the generic method
        //      Generic declaration of a generic method, declared before the method name when called
        student.<String, Integer>getData2("Mouse");

        // Generic types can also not be declared in generic methods
        //      The parameter passed in is a generic T type
        //      If String is set for the incoming parameter, the generic T is implicitly set to String type
        String data3 = student.getData2("Mouse");


        // The compiler checks at compile time
        List<String> list1 = new ArrayList<>();
        list1.add(1);

        // The compiler does not check at compile time
        List list2 = new ArrayList<String>();
        //list2.add(1);
    }
}

Posted by scrupul0us on Wed, 08 Sep 2021 00:34:27 -0700