Reflection and annotation

Posted by grandadevans on Sat, 15 Jan 2022 19:25:28 +0100

I reflex

1. Concept

Reflection: it means that our program can get Class Object, go"reverse"Loading of"A class",And create an object and call its properties and methods.
Function: Unlock the relationship between classes"Coupling relationship",It is conducive to the later development and maintenance of the program!!!

2. Class loader

1. Class loading:

1). When our program first uses a class (create an object, access its static members...) (except constants),
The JVM will read the class file of this class on the hard disk.
2).Java stores the class information of any class used during program operation in the "method area",
Will create one and only one Class object for it.
For example: Student class, System class, Scanner class, Random class, ArrayList class
This is why we learned the "static synchronization method" before. Its lock object is the Class object of this Class.
public synchronized static void show(){
}
3). When the JVM loads our class file, it also uses a "class". This class is called class loader in the JVM:

2. There are three kinds of loaders in Java:

​ 1). Bootstrap classloader: used to load the System class library < Java_ Class in the home > \ bin directory, for example: rt.jar. (for example: System class, Random class, ArrayList class)
2). Extension classloader: used to load the extension class library < Java_ Class in the home > \ lib \ ext directory.
3). Application classloader: used to load our customized loader (e.g. Student class, Phone class...)
Class JVM loads a class and uses the "two parent delegation model":
When we want to load a class:
For example: Student class – > JVM – > application class loader – > delegate to "extended class loader" – > delegate to "startup class loader". It is found that the application class loader cannot be loaded < – "extended class loader" < –

3. There are three ways to obtain Class objects, the premise of reflection

1).Object Class: getClass()[Class suitable for obtaining class library Class]
2).Any data type(Include basic data types): data type.class[Class suitable for obtaining class library Class]
3).Class Static method of forName(String Full class name): Class.forName(String Full class name)[Commonly used-Suitable for getting our custom classes Class [object]
Note: the above three methods will first judge whether there is Class Object, if not, will be read class File, and then create its in the method area Class Object.

4. Reflection acquisition construction method (obtained through Class object) to create object

1).Batch acquisition:[understand]
    1).public Constructor[] getConstructors(): Get all"Public construction method"
            Each public constructor is encapsulated as a Constructor Object, multiple Constructor Object is encapsulated into an array and returned.
    2).public Constructor[] getDeclaredConstructors(): Get all construction methods, including public, protected, default and private.
2).Get single:[master]
    3).public Constructor getConstructor(Class ... parameterTypes): Get a"Public construction method"
    4).public Constructor getDeclaredConstructor(Class ... parameterTypes): Gets the constructor of any.

    Call the constructor of this class:
    Constructor(Represents a construction method)-->newInstance(Argument)
    If this constructor is called, no"jurisdiction(Restrictions on access modifiers)",First set: violent access
    If you have access rights, you can also set"Violent visit"
    Constructor-->setAccessible(true)
    tip: 
        If the parameterless construction of a class is public,Can be used directly  class object.newInstance

5. Reflection property (obtained through Class object)

1).Batch acquisition:[understand]
    1).public Field[] getFields(): Get all"Public member properties"
            Each public member property is encapsulated as a Field Object, multiple Field Object is encapsulated into an array and returned.
    2).public Field[] getDeclaredFields(): Get all member properties, including public, protected, default and private.

2).Get single:[master]
    3).public Field getField(String fieldName): adopt"Attribute name",Get a"Public member properties"
    4).public Field getDeclaredField(String fieldName): Get the member property of any access right through the property name.

    be careful:
    1).To assign a value to an attribute, you must first create such an object;
    2).Assignment: Field-->set(Object targetObj,Object value): 
            If you do not have access rights, set brute force access
            Field-->setAccessible(true)

    3).Get value: Field-->get(Object targetObj)

6. Reflection property (obtained through Class object)

1).Batch acquisition:[understand]
    1).public Method[] getMethods(): Get all"Public member method"
            Each public member method is encapsulated as a Method Object, multiple Method Object is encapsulated into an array and returned.
    2).public Method[] getDeclaredMethods(): Get all member methods, including public, protected, default and private.


2).Get single:[master]
    3).public Method getMethod(String methodName,Class... params): adopt"Method name, parameter Class",Get a"Public member method"
    4).public Method getDeclaredMethod(String methodName,Class ... params): By method name and parameter Class,Member method that gets any access rights.

    Call method: Method Class-->invoke(Object targetObj,Object ... params)
    If you do not have access rights, you need to set brute force access:
            Method Class-->setAccessible(true)

7. Reflection can skip collection generic detection Generic erasure mechanism

//Generics are always identified as Object classes when compiling
public class Practice {
    public static void main(String[] args) throws Exception {
        List<String> list = new ArrayList<>();
        list.add("Bingbing");
        list.add("Qiuya");
        list.add("Winter plum");
        Class<? extends List> clazz = list.getClass();
        Method addMethod = clazz.getMethod("add", Object.class);
        //Here, the Student type is added by calling the method through reflection
        addMethod.invoke(list,new Student("Zhao Min",23));
        System.out.println(list);
    }
}

II Annotation annotation

1. Usage

from JDK1.5 Start, Java Proposed"annotation",
    For example:@Override(When overriding a method)  //Class life cycle compilation period
         @FunctionalInterface(Define functional interfaces) // Lifecycle Class
         @Test(JUnit tool)   //Lifecycle Runtime
 Function of annotation: write in"Source code"In, tell"Annotation parser",The following code how to compile and run.

The application of annotations includes: + Annotation parser(program)

A).Notes:
    1).We can define our own annotations
        public @interface MyTest {
        }
    2).Use notes:
        @MyTest
        public class Student {
            @MyTest
            private String name;

            @MyTest
            public void show(){
                System.out.println("ha-ha");
            }
        }
        Note: this annotation can be used at this time, but it has no effect

    3).Meta annotation: Java The annotation defined in the class library is used in"Definition of annotation"On, used for annotation"constraint"(i.e. the annotation used to define the annotation):
        1).@Target: Constrains the of the newly defined annotation"Use location"

            For example:@Target(ElementType.METHOD)You can constrain that new annotations can only be used on: methods

            ElementType Common values for:
                  1).TYPE: Class, interface
                  2).FIELD: Member variable
                  3).METHOD, Member method
                  4).PARAMETER, Method parameters
                  5).CONSTRUCTOR, Construction method
                  6).LOCAL_VARIABLE, local variable

        2).@Retention: Constrains the of the newly defined annotation"life cycle"
            For example:@Retention(RetentionPolicy.SOURCE)Can constrain the lifecycle of annotations: source code

            RetentionPolicy Value of:
                  1).SOURCE: In the source code. Will not compile to class File. Function: to the compiler"Annotation parser"Look. For example:@Override
                  2).CLASS: In the source code class File. However, at runtime, it will not be loaded into runtime memory.
                  3).RUNTIME: In the source code class File, runtime memory. For example:@Test
B).Annotation parser
        Use reflection to create objects of classes that use annotations
        After reflection, get the components of the class,
        call isAnnotationPresent Method to determine whether an annotation is used.class


C).Attribute of annotation: the meta annotation just used has attributes:
            @Target(ElementType.METHOD)
            Among them ElementType.METHOD Is the attribute

   Function of attribute: can be more detailed"Comments on the new definition"constraint"
   Format of attributes defined in annotation:
    public @interface MyTest {
        //Format of attribute: data type name attribute name () [default value];
        int index() default 0;  //After the attribute is defined, it must be assigned when using it, otherwise an error will be reported
        //After the default value is defined, the default value can be used without assignment in the class using annotation, or the displayed value can be reassigned
    }

   Property acquisition:
        You can get the annotated part by reflection and call getAnnotation(Annotation .class)Method to get the annotation object
        Annotation object.attribute(),The annotation attribute value can be obtained
   be careful:
   1).There can only be eight data types String,Class,Annotation type, enumeration type, and the above types"array"Type. [recite]
   2).If an annotation has an attribute named: value,Moreover, other properties have default values, and only need to be set when using this annotation value Property, you can omit:"value = ",Write values directly.

2. User defined annotation

Requirements:
    Make one"Annotation parser",Simulated use JUnit of@Test Annotation: right click-->Run "xxxx.show()"Function menu.
    1.Customize an annotation and constrain it to be defined on the method, and the life cycle is runtime
    2.Custom classes, Student,Add custom annotations to a method
    3.Define an annotation parser, parse annotated methods, and execute
    4.1 Get all the methods of the annotated class, and sort the methods with the method name
    4.2 Defined in annotation int Type index Property to obtain all methods of the annotated class by reflection index Property to sort the methods

annotation

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    int index();
}

Annotated classes

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @MyAnno(index = 3)
    public void eat(){
        System.out.println("eat");
    }
    @MyAnno(index = 19)
    public void sleep(){
        System.out.println("sleep");
    }
    @MyAnno(index = 9)
    public void love(){
        System.out.println("love");
    }
    public void fen(){
        System.out.println("branch");
    }
}

Annotation parsing class

public class Demo {
    public static void main(String[] args) throws Exception {
        List<Method> list = new ArrayList<>();
        Class<Student> clazz = Student.class;
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if(method.isAnnotationPresent(MyAnno.class)){
                method.invoke(stu);
                list.add(method);
            }
        }
        //4.1 get all the methods of the annotated class, and sort the methods with the method name
        Collections.sort(list, new Comparator<Method>() {
            @Override
            public int compare(Method o1, Method o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        System.out.println("-------The method name sorts the methods----------");
        for (Method method : list) {
            System.out.println(method);
        }
        //4.2 define the index attribute of int type in the annotation, use reflection to obtain all methods of the annotated class, and use the index attribute of the annotation to sort the methods
        System.out.println("-------according to index Sort of----------");
        Collections.sort(list, new Comparator<Method>() {
            @Override
            public int compare(Method o1, Method o2) {
                return o1.getAnnotation(MyAnno.class).index()-o2.getAnnotation(MyAnno.class).index();
            }
        });
        for (Method method : list) {
            System.out.println(method+" index="+method.getAnnotation(MyAnno.class).index());
        }
    }
}

III proxy pattern

1. What is "design pattern":

Mode: some fixed ways and processes to solve a problem. For example: profit model, working model, learning model
Java design pattern: refers to a fixed design method for some problems by using some syntax features of Java (inheritance, encapsulation, polymorphism...).

2. There are many design patterns defined in Java (more than 20 and more than 40-50 extended), and there are special books to introduce Java design patterns.

3. Agency mode:

Problem solved: provide "function enhancement" for the methods of the original class without changing the code of the original class

The "agent model" is similar to the "agent" in reality.

Agent enhancement, decorator mode

4.java Dynamic agent API

Dynamic agent: refers to a program that can run at runtime"Dynamic"For a"Proxy class"Generate a"Dynamic proxy object",And method enhancement can be carried out.
be careful: JDK The dynamic proxy provided is based on"Interface"Yes - all required"Proxied class"The same interface must be implemented to have the same function

Dynamic proxy class:Proxy
    Generation agent method public static Object newProxyInstance(ClassLoader loader,
                                                        Class<?>[] interfaces,
                                                        InvocationHandler h)
    Parameters: loader  Class loader, proxy class"Class loader",And"Proxy class"Same as
    Parameters: interfaces  Proxy class"Parent interface",And"Proxy class"identical
    Parameters: h  Execution agent control object

    InvocationHandler Methods in the interface:
            public Object invoke(Object proxy, Method method, Object[] args)
           Function of the method: when the agent calls any method, it will be intercepted and executed by the method
                             Whether to execute the original method of the agent can be judged according to logic,
                             And the method can be enhanced, that is, other logic can be executed before and after the execution of the original method.
            Parameter Description:
                 proxy;Generated proxy object[Not used]
                 method: Method object executed by proxy
                 args: Parameters of the method being executed by the proxy
                 return Proxy object	

5. Agency model case

demand

Define interface IStar#sing#dance
 Define class Cxk,realization IStar Interface
    sing Method print real singing, very ugly singing
    dance Method printing, fancy basketball playing method, basketball playing well
Demo Medium:
    establish Cxk object
    establish Cxk Object's proxy object
        Agent execution logic:
            If it is sing The method is to sing on behalf of a real man
            If it is dance Method, let the agent jump by himself
    Execution using proxy objects sing Method and dance Method to complete the proxy call.

Proxy class

public class Cxk implements DaiLi{
    public void sing(){
        System.out.println("Real singing, very ugly singing");
    }
    public void dance(){
        System.out.println("Fancy basketball play, basketball play well");
    }

    @Override
    public int yanDianYing(String name) {
        System.out.println("Classic reproduction "+name);
        return 9;
    }
}

The proxy class implements the interface

public interface IStar {
    void sing();
    void dance();
}

Agent test class

public class Demo {
    public static void main(String[] args) {
       Cxk cxk = new Cxk();
       //Proxy.newProxyInstance
        //First parameter class loader
        ClassLoader classLoader = Cxk.class.getClassLoader();
        //The second parameter implements an array of all interfaces
        Class<?>[] interfaces = Cxk.class.getInterfaces();
        IStar proxy = (IStar) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if("sing".equals(method.getName())){
                    System.out.println("Substitute singing,It's really not funny");
                }
                if("dance".equals(method.getName())){
                    method.invoke("sing,jump,rap"+cxk);
                }
                return null;
            }
        });
        proxy.sing();
        proxy.dance();
    }
}

Topics: Java Back-end