Java core technology Chapter 8 - Generic

Summary

According to "Java core technology Volume" summed up from eighth chapter of the book, in the part of the article excerpt the book, as personal notes.
Article not too deep, hope readers will be good reference.

Why use generic programming

Generic programming (Generic programming) code written means can be reused by many different types of objects.

Benefits type of the parameter

In the absence of a generic class, ArrayList class only to maintain an array of Object references:

public class ArrayList {
   private Object[] elementData; // 用于存放数据
   public Object get(int i) { . . . }
   public void add(Object o) { . . . }
     ...
}

problem

Must be cast Gets a value 1.
2. there is no error checking. You can add the list to an array of objects of any type, if inconsistent with the type of the array, will get the results of mandatory mandatory, an error.

Generics provide a better solution: type parameter:

ArrayList<String> array = new ArrayList<String>():

Information on the use of type parameters, we can maintain the type of unity when adding data, call the get method does not need time to be cast, because when we initialized it defines the type, the compiler will identify the type of the return value help us convert the type.

Defining a simple generic class

public class Pair<T> {
    private T num;

    public Pair(T num) { this.num = num; }
    public T getNum() { return num; }
    public void setNum(T num) { this.num = num; }
}

We can see that in the back of the class name added a Pair This is a generic class type variables, but also a plurality of types of variables, such as

public class Pair<T,U> {
    ...
}

If we instantiate Pair class, for example:

new Pair<String>;

Then we can think of the above-mentioned Pair class as follows:

public class Pair<String> {
    private String num;

    public Pair(String num) { this.num = num; }
    public String getNum() { return num; }
    public void setNum(String num) { this.num = num; }
}

Is not it simple? In Java libraries, using the variable E represents the set of element types, K and V respectively represent the type keywords and values ​​table, T, U, S represents any type.

Generic method

The method is defined with a parameter of type

    public static <T> T getMiddle(T... a) {
        return a[a.length / 2];
    }

You can see the type of a variable (<T>) on the back modifier (public static), the return type (T) above. Generic methods can be defined in a generic class or an ordinary class.

Defining a type of the variable

If we need to be constraints on the type of variables such as: passing variables must implement the Comparable interface, because the variable method calls the compareTo needs. So that we can use extendsthe keyword to define variables.

    public <T extends Comparable> T max(T a) {
        a.compareTo(...);
        ...
    }

Whether defined variables need to inherit a class or implements an interface, you are using extendsthe keyword limit.

Generic code and virtual machine

Type erasure

Whether we have a generic class, generic method how defined in the code, it provides a corresponding primitive type. Deleting the original type name is the name of the generic class type parameters. The <T>original type of Object, <T extends MyClass>the original type MyClass.
Code like this:

public class Pair<T> {
    private T property;

    public Pair(T property) {
        this.property = property;
    }
}

After type erasure:

public class Pair<Object> {
    private Object property;

    public Pair(Object property) {
        this.property = property;
    }
}

Translation generic expression

If you erase the return type, the compiler inserts casts, such as the following:

Pair<Employee> buddies = . .
Employee buddy = buddies.getFirst();

Erase getFirst return after return type of type Object, but the compiler will automatically help us cast to Employee.
So: the compiler to perform operations of this method is divided into two instructions:

Pair.getFirst call to the original method of
the Object return type cast to type Employee

Section Summary:

No generic virtual machine, only the classes and methods common
to all types of the parameters are replaced with their type is defined
as a holding type safety, if necessary insert cast
bridge held synthesis methods are polymorphic (not mentioned herein, but the bridge method can be ignored, Java will have to write non-standard method bridge generation)

Restrictions and Limitations

Examples of the basic types can not use the type of parameter

Eight basic data types can not be used to instantiate a type parameter, you have not seen ArrayList<int>such a code it. Only ArrayList<Integer>. The reason is because the basic data type is not Object. So they can only be replaced with a type of packaging.

Run-time type query applies only to the original type

All types of queries produced only primitive type, because no such thing as a generic type in a virtual machine.
E.g:

    Pair<String> pair = new Pair<String>("johnson");
    if (pair instanceof Pair<String>) {} // Error
    if (pair instanceof Pair<T>) {} // Error
    if (pair instanceof Pair) {} // Pass

You can not create arrays of parameterized types

    Pair<String>[] pairs = new Pair<String>[10]; //error

Why can not this definition? Because pairsof the type Pair[], it can be converted Object[], if you try to store other types of elements, an exception will be thrown ArrayStoreException,

    pairs[0] = 10L; //抛异常

In a word, not strict. You can not create a parameterized type of array.

Type variable can not instantiate

You can not use new T (...), new T [...] or T.class. Because the type erasure, T will become Object, and we are certainly not want to instantiate Object.
But after Java8, we can use the Supplier<T>interface, which is a functional interface that represents a parameter and there is no return type of the function T:

public class Pair<T> {
    private T first;
    private T second;

    private Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public static <T> Pair<T> makePair(Supplier<T> constr) {
        return new Pair<>(constr.get(), constr.get());
    }
    
    public static void main(String[] args) {
        Pair<String> pair = Pair.makePair(String::new);
    }
}

The generic class type variable static context is invalid

You can not reference type variable domain or in a static method. E.g:

public class Pair<T> {
    private static T instance; //Error

    public static T getInstance() { //Error
        if (instance == null) 
            instance = new Pair<T>();
        return instance;
    }
}

Because the class type variable (<T>)is the effective scope of the object, instead of a valid class in scope. If you are using a generic method, the article may refer to the above generic methods oh ~

Not throw or capture instance of a generic class

That can not throw objects can not capture a generic class, even extend Throwable is illegal:

public class Pair<String> extend Exceotion {} //Error
public static <T extends Throwable> void doWork(Class<T> t) {
    try {
        ...
    } catch (T e) { //Error
        ...
    }
}

But after throwing an exception to an exception to allow the use of variable types (personal feeling never seen such a code).

public static <T extends Throwable> void doWork(Class<T> t) throw T { //Pass
    try {
        ...
    } catch (Exception e) {
        throw e;
    }
}

Generic type of inheritance rules

Such as Managerclass inheritance Employeeclass. But Pair<Employee>and Pair<Manager>is not associated. Like the following code, will prompt an error, delivery failures:

        Pair<Manager> managerPair = new Pair<Manager>();
        Pair<Employee> employeePair = managerPair; //Error

Wildcard type

Wildcard concept

Wildcard type, allowing the change type parameter, using ?identification wildcard type:

Pair<? extends Employee>

If the class is as follows Pair

public class Pair<T> {
    private T object;

    public void setObject(T object) {
        this.object = object;
    }
}

Then you can use wildcards to resolve generic types of rules of succession issues, such as:

        Pair<Manager> managerPair = new Pair<Manager>();
        Pair<? extends Employee> employeePair = managerPair; //Pass
        Manager manager = new Manager();
        employeePair.setObject(manager); //Error

Use <? Extends Employee>, the compiler only knows employeePair is a subclass of Employee, but it is unclear what specific sub-categories, so the final step employeePair.setObject(manager)can not be executed.

Wildcard defining supertype

Wildcard has an additional capability, you may be designated a super-defined type , such as:

public class Pair<T> [
    ...
    public static void salary(Pair<? super Manager> result) {
        //...
    }
}

<? super Manager>The wildcard for all types of ultra Manager (including Manger), for example:

        Pair<Manager> managerPair = new Pair<Manager>();
        Pair<Employee> employeePair = new Pair<Employee>();

        Pair.salary(managerPair); //Pass
        Pair.salary(employeePair); //Pass

        // 假如 ManagerChild为Manager子类
        Pair<ManagerChild> managerChildPair = new Pair<ManagerChild>();
        Pair.salary(managerChildPair); //Error

Indefinite wildcard

Indefinite wildcards, such as: Pair<?>when we do not need to care about his actual type when you can use a wildcard indefinite, on the code:

    public static boolean hasNull(Pair<?> pair) {
        return pair.getObject() == null;
    }

To be honest, it made me dizzy wildcards, see the article over and over again, slowly began to understand that I was too hard. . .


Article here came to an end, do not know you did not read the small partner, did not understand the words may be my article writing skills and the ability to be improved, small partners can also take a look "Java core technology Volume" This book it, the feeling is very good. Recently picked up this book point of view is also found that the foundation is very important, first precipitated good foundation, and then learning other technical points will be easier to start with, will know these know the course. Recently very much like a word, he gave us: "oaks from little acorns, not in quicksand high-profile building."

Personal blog URL: https://colablog.cn/

If my articles help to you, I can focus on the public micro-channel number, the first time to share your article

Micro-channel public number

Guess you like

Origin www.cnblogs.com/Johnson-lin/p/11981994.html