Java annotation and reflection mechanism

Java annotation

Introduction to annotation

  • Annotation is from jdk5 0 began to introduce new technologies that can be used for checking and constraints

  • Function of Annotation:

    • It's not the procedure itself. It can be explained (this is no different from a comment.)
    • It can be read by other programs (such as compiler, etc.)
  • Format of Annotation:

    • The annotation exists in the code as "@ annotation name", and some parameter values can be added
    • For example: @ SuppressWarnings(value = "unchecked")
  • Where is Annotation used?

    • It can be attached to package, class, method, field, etc., which is equivalent to adding additional auxiliary information to them. We can access these metadata through reflection mechanism programming

Built in annotation

  • @Override: defined in Java In lang. override, this annotation is only applicable to rhetoric, indicating that one method declaration intends to override another method declaration in the superclass

  • @Deprecated: defined in Java In lang. deprecated, this annotation can be used for rhetoric, attributes, and classes to indicate that programmers are not encouraged to use such elements, usually because it is dangerous or there are better choices

  • @suppressWarnings: defined in Java In lang. suppressWarnings, the warning information used to suppress compilation is different from the first two comments. You need to add a parameter to use it correctly. These parameters have been defined. We can use them selectively

    • @SuppressWarnings("all")
    • @SuppressWarnings("unchecked")
    • @SuppressWarnings(value={"unchecked","deprecation"})
    package Annotation;
    
    import java.util.ArrayList;
    import java.util.List;
    
    //What is annotation
    public class Demo01 extends Object{
    
        //@Override overridden annotation
        @Override
        public String toString() {
            return super.toString();
        }
    
        //@Deprecated is not recommended, but it can be used, or there is a better way
        @Deprecated
        public static void test(){
            System.out.println("Deprecated");
        }
    
        //@SuppressWarnings are generally not used
        @SuppressWarnings("all")
        public void test02(){
            List list = new ArrayList();
        }
    
        public static void main(String[] args) {
            test();
        }
    
    }
    
    

Meta annotation

  • The function of meta annotation is to annotate other annotations. Java defines four standard meta annotation types, which are used to describe other annotation types

  • These types and the classes they support are in Java You can find it in the lang.annotation package (Target , @Retention@Documented , @lnherited )

    • @Target: used to describe the scope of use of annotations (i.e. where the described annotations can be used)

    • @Retention: indicates the level at which the annotation information needs to be saved. It is used to describe the annotation life cycle

      • (SOURCE<CLASS < RUNTIME)
    • @Document: note that the annotation will be included in javadoc

    • @Inherited: indicates that the subclass can inherit the annotation in the parent class

      package Annotation;
      
      import java.lang.annotation.*;
      
      //Test meta annotation
      @MyAnnotation//     ElementType needs to be defined TYPE
      public class Demo02 {
      
          @MyAnnotation//     ElementType needs to be defined METHOD
          public static void main(String[] args) {
      
          }
      }
      
      
      //Define an annotation
      //Target indicates where our annotation can be used
      @Target(value = {ElementType.METHOD,ElementType.TYPE})
      
      //Retention indicates where our annotation is still valid
      // runtime > class > sources
      @Retention(value = RetentionPolicy.RUNTIME)
      
      //Documented indicates whether our annotations are generated in JAVAdoc
      @Documented
      
      //The Inherited subclass can inherit the annotation of the parent class
      @Inherited
      @interface MyAnnotation{
      
      }
      
      

Custom annotation

  • When using @ interface to customize the annotation, java.com is automatically inherited lang.annotation. Annotation interface

  • analysis

    • Interface is used to declare an annotation. Format: public @interface annotation name {definition content} √ each method actually declares a configuration parameter

    • The name of the method is the name of the parameter

    • The return value type is the type of the parameter (the return value can only be the basic type, class, string, enum)

    • You can declare the default value of the parameter through default

    • If there is only one parameter member, the general parameter name is value

    • An annotation element must have a value. When defining an annotation element, we often use an empty string with 0 as the default value

      package Annotation;
      
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      //Custom annotation
      public class Demo03 {
      
          //Annotations can be assigned explicitly. If there is no default value, we must assign a value to the annotation
          @MyAnnotation2(name = "zy",schools = {"Zhejiang","Science and Engineering"})
          public void test(){}
      
          //Only one parameter is recommended to be named with value, and value can be omitted=
          @MyAnnotation3("zy")
          public void test2(){}
      
      
      }
      
      
      @Target({ElementType.TYPE,ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      @interface MyAnnotation2{
          //Annotated parameters: parameter type + parameter name ()
          String name() default "";
          int age() default 0;
          int id() default -1;//If the default value is - 1, it means that it does not exist
      
          String[] schools() default "Zhejiang University of Technology";
      }
      
      @Target({ElementType.TYPE,ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      @interface MyAnnotation3{
          String value();
      }
      
      

Java reflection mechanism

Overview of reflection mechanism

  • Dynamic language

    • It is a kind of language that can change its structure at run time: for example, new functions, objects and even code can be introduced, existing functions can be deleted or other structural changes. Generally speaking, the code can change its structure according to some conditions at run time
    • Main dynamic languages: Object-C, c#, JavaScript, PHP, Python, etc
  • Static language

    • Corresponding to dynamic language, the language with immutable runtime structure is static language. Such as Java, C, C++
    • Java is not a dynamic language, but Java can be called a "quasi dynamic language". That is, Java has certain dynamics. We can use reflection mechanism to obtain characteristics similar to dynamic language. The dynamic nature of Java makes programming more flexible!
  • reflex

    • Reflection is the key to Java being regarded as a dynamic language. The reflection mechanism allows the program to obtain the internal information of any class with the help of Reflection API during execution, and can directly operate the internal properties and methods of any object

      Class c= Class.forName("java.lang.String")
      
    • After loading the Class, an object of Class type is generated in the method area of heap memory (a Class has only one Class object), which contains the complete structure information of the Class. We can see the structure of the Class through this object. This object is like a mirror, through which we can see the structure of the Class. Therefore, we call it reflection

    • Functions provided by reflection mechanism

      • Determine the class of any object at run time
      • Construct an object of any class at run time
      • Judge the member variables and methods of any class at run time
      • Get generic information at runtime
      • Call the member variables and methods of any object at run time
      • Processing annotations at run time
      • Generate dynamic proxy
    • Advantages: it can dynamically create objects and compile, reflecting great flexibility

    • Disadvantages: it has an impact on performance. Using reflection is basically an interpretive operation. We can tell the JVM what we want it to do and it meets our requirements. Such operations are always slower than performing the same operation

    • Reflection related API

      • java.lang.Class: represents a class
      • java.lang.reflect.Method: represents the method of the class
      • java.lang.reflect.Field: represents the member of the class
      • java.lang.reflect.Constructor: represents the constructor of the class
    package Reflection;
    
    //What is reflection
    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException {
            //Get the class object of the class through reflection
            Class c1 = Class.forName("Reflection.User");
            System.out.println(c1);
    
            Class c2 = Class.forName("Reflection.User");
            Class c3 = Class.forName("Reflection.User");
            Class c4 = Class.forName("Reflection.User");
    
            //A class has only one class object in memory
            //After a Class is loaded, the whole structure of the Class will be encapsulated in the Class object
            System.out.println(c2.hashCode());
            System.out.println(c3.hashCode());
            System.out.println(c4.hashCode());
        }
    
    }
    
    //Entity class: POJO entity
    class User{
    
        private String name;
        private int id;
        private int age;
    
        public User() {
        }
    
        public User(String name, int id, int age) {
            this.name = name;
            this.id = id;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    

Understand Class and get Class instances

  • The following methods are defined in the Object class, which are inherited by all subclasses

    public final Class getClass()
    
  • The type of the return value of the above method is a Class class, which is the source of Java reflection. In fact, the so-called reflection is also well understood from the running results of the program, that is, the name of the Class can be obtained through object reflection

    Method nameFunction description
    static ClassforName(String name)Returns the Class object with the specified Class name
    Object newInstance()Call the default constructor to return an instance of the Class object
    getName()Returns the name of the entity (Class, interface, array Class or void) represented by the current Class object
    Class getSuperClass()Returns the Class object of the parent Class of the current Class object
    Class[] getinterfaces()Gets the interface of the current Class object
    ClassLoader getClassLoader()Returns the class loader for this class
    Constructor[] getConstructor()Returns an array containing some Constructor objects
    Method getMonthed(String name, Class... T)Returns a Method object whose formal parameter type is parameterType
    Field[] getDeclaredFields()Returns an array of Field objects
  • Get an instance of Class

    • Given a specific Class, this method is the most safe and reliable and has the highest programmability by obtaining it through the Class attribute of the Class

      Class clazz = Persono.class;
      
    • If the instance of a Class is known, call the getClass() method of the instance to get the Class object

      Class clazz = person.getClass();
      
    • If the full Class name of a Class is known and the Class is under the Class path, it can be obtained through the static method forName() of Class class, and ClassNotFoundException may be thrown

      Class clazz = Class.forName("demo01.Student")
      
    • The built-in basic data type can use the class name directly Type

    • You can also use ClassLoader

      package Reflection.TextClass;
      
      //What are the ways to create the test class
      public class Demo01 {
          public static void main(String[] args) throws ClassNotFoundException {
              Person person = new Student();
              System.out.println("This person is:" + person.name);
      
              //Method 1: obtained by object
              Class c1 = person.getClass();
              System.out.println(c1.hashCode());
      
              //Method 2: forname
              Class c2 = Class.forName("Reflection.TextClass.Student");
              System.out.println(c2.hashCode());
      
              //Method 3: pass the class name Class get
              Class c3 = Student.class;
              System.out.println(c3.hashCode());
      
              //Method 4: packing classes of basic built-in types have a Type attribute
              Class c4 = Integer.TYPE;
              System.out.println(c4);
      
              //Get parent type
              Class c5 = c1.getSuperclass();
              System.out.println(c5);
      
          }
      }
      
      class Person{
          public String name;
      
          public Person() {
          }
      
          public Person(String name) {
              this.name = name;
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "name='" + name + '\'' +
                      '}';
          }
      }
      
      class Student extends Person{
          public Student(){
              this.name = "student";
          }
      }
      
      class Teacher extends Person{
          public Teacher(){
              this.name = "teacher";
          }
      }
      
  • What types can have Class objects

    • Class: external class, member (member internal class, static internal class), local internal class, anonymous internal class
    • interface: interface
    • []: array
    • enum: Enumeration
    • Annotation: annotation @ interface
    • primitive type: basic data type
    • void
    package Reflection.TextClass;
    
    import java.lang.annotation.ElementType;
    
    //Class of all types
    public class Demo02 {
        public static void main(String[] args) {
            Class c1 = Object.class;//class
            Class c2 = Comparable.class;//Interface
            Class c3 = String[].class;//One dimensional array
            Class c4 = int[][].class;//Two dimensional array
            Class c5 = Override.class;//annotation
            Class c6 = ElementType.class;//enumeration
            Class c7 = Integer.class;//Basic data type
            Class c8 = void.class;//void
            Class c9 = Class.class;//Class
    
            System.out.println(c1);
            System.out.println(c2);
            System.out.println(c3);
            System.out.println(c4);
            System.out.println(c5);
            System.out.println(c6);
            System.out.println(c7);
            System.out.println(c8);
            System.out.println(c9);
    
            //As long as the element type is the same as the dimension, it is a Class
            int[] a = new int[10];
            int[] b = new int[100];
    
            System.out.println(a.getClass().hashCode());
            System.out.println(b.getClass().hashCode());
    
        }
    }
    
    

Class loading and CLassLoader

  • The information that can be obtained after the object looks in the mirror: the properties, methods and constructors of a Class, and which interfaces a Class implements. For each Class, the JRE keeps an object of the same Class type for it. A Class object contains information about a specific structure (Class / interfaceenum / annotation / primitive type / void /).
    • Class itself is also a class
    • Class objects can only be created by the system
    • A loaded Class will only have one Class instance in the JVM
    • A class object corresponds to one loaded into the JVM Class file
    • Each Class instance will remember which Class instance it was generated from
    • All loaded structures in a Class can be completely obtained through Class
    • Class is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first

Class load memory analysis

  • Load: load the bytecode content of the class file into memory, convert these static data into the runtime data structure of the method area, and then generate a Java. XML file representing this class Lang.class object

  • Link: the process of merging the binary code of Java classes into the running state of the JVM

    • Verification: ensure that the loaded class information complies with the JVM specification and there are no security problems
    • These variables are allocated in the initial memory preparation (default) stage of the class
    • Resolution: the process of replacing the symbolic reference (constant name) in the virtual machine constant pool with a direct reference (address)
  • initialization:

    • The process of executing a class constructor () method. The class constructor () method is generated by the combination of the assignment actions of all class variables in the class automatically collected at compile time and the statements in the static code block. (the class constructor is the constructor that constructs class information, not the constructor that constructs the class object.).
    • When initializing a class, if you find that its parent class has not been initialized, you need to trigger the initialization of its parent class first
    • Virtual chance ensures that the () methods of a class are locked and synchronized correctly in a multithreaded environment.
    package Reflection.TextClass;
    
    /*
    1.When loaded into memory, a class object corresponding to the class will be generated
    2.Link, m = 0 after link
    3.initialization
        <clinit>(){
            System.out.println("A Class static code block initialization "");
            m = 300;
            m = 100;
        }
    
        m = 100
     */
    public class Demo03 {
        public static void main(String[] args) {
            A a = new A();
            System.out.println(A.m);
        }
    
    }
    
    class A{
        static {
            System.out.println("A Class static code block initialization");
            m = 300;
    
        }
    
        static int m = 100;
    
        public A(){
            System.out.println("A Class's parameterless construction initialization");
        }
    
    }
    

When will initialization occur

  • Active reference of class (class initialization is bound to occur)

    • When the virtual machine starts, initialize the class where the main method is located first
    • new is an object of a class
    • Call static members (except final constants) and static methods of the class
    • Using Java The method of lang.reflect package makes reflection calls to the class
    • When initializing a class, if its parent class is not initialized, its parent class will be initialized first
  • Passive reference of class (class initialization will not occur)

    • When accessing a static domain, only the class that actually declares the domain will be initialized. For example, when a static variable of a parent class is referenced through a subclass, the subclass will not be initialized
    • Defining a class reference through an array does not trigger the initialization of this class
    • Reference constants do not trigger the initialization of this class (constants are stored in the constant pool of the calling class in the link phase)
    package Reflection.TextClass;
    
    //When will the test class initialize
    public class Demo04 {
    
        static {
            System.out.println("main Class is loaded");
        }
    
        public static void main(String[] args) throws ClassNotFoundException {
            //1. Active quotation
            // son = new Son();
    
            //2. Reflection also produces active references
            //Class c1 = Class.forName("Reflection.TextClass.Son");
    
    
            //A method that does not generate a reference to a class
            //System.out.println(Son.b);
    
            //Son[] array = new Son[5];
    
            System.out.println(Son.M);
        }
    
    }
    
    class Father{
    
        static int b = 2;
    
        static {
            System.out.println("Parent class loaded");
        }
    
    }
    
    class Son extends Father{
    
        static {
            System.out.println("Subclass loaded");
            m = 300;
        }
    
        static  int m = 100;
        static final int M =1;
    
    }
    

Role of class loader

  • The function of class loading: load the bytecode content of the class file into memory, convert these static data into the runtime data structure of the method area, and then generate a Java. XML file representing this class in the heap Lang. class object, as the access entry of class data in the method area

  • Class caching: the standard Java se class loader can find classes as required, but once a class is loaded into the class loader, it will remain loaded (cached) for a period of time. However, the JVM garbage collection mechanism can recycle these class objects

    package Reflection.TextClass;
    
    public class Demo05 {
        public static void main(String[] args) throws ClassNotFoundException {
    
            //Gets the loader of the system class
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);
    
            //Get the parent class loader -- > extension class loader of the system class loader
            ClassLoader parent = systemClassLoader.getParent();
            System.out.println(parent);
    
            //Gets the parent class loader -- > root loader of the extension class loader
            ClassLoader parent1 = parent.getParent();
            System.out.println(parent1);
    
            //Test which loader loads the current class
            ClassLoader classLoader = Class.forName("Reflection.TextClass.Demo05").getClassLoader();
            System.out.println(classLoader);
    
            //Test who loaded the built-in classes in JDK
            classLoader = Class.forName("java.lang.Object").getClassLoader();
            System.out.println(classLoader);
    
            //How to get the path that the system class loader can load
            System.out.println(System.getProperty("java.class.path"));
    
            //Parental delegation mechanism
            //java.lang.String custom useless
    
            /*
            D:\JAVA\jdk1.8.0_301\jre\lib\charsets.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\deploy.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\dnsns.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\jaccess.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\localedata.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\nashorn.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\sunec.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\ext\zipfs.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\javaws.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\jce.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\jfr.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\jfxswt.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\jsse.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\management-agent.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\plugin.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\resources.jar;
            D:\JAVA\jdk1.8.0_301\jre\lib\rt.jar;
            C:\Users\22866\Desktop\JavaSE\out\production\JavaSE;
            C:\Users\22866\Desktop\JavaSE\JavaSE\src\lib\commons-io-2.11.0.jar;
            D:\IntelliJ IDEA\IntelliJ IDEA 2021.1.1\lib\idea_rt.jar
    
             */
        }
    }
    

Gets the complete structure of the runtime class

  • Get the complete structure of the runtime class through reflection

  • Field,Method,Constructor,Superclass,Interface,Annotation

    • All interfaces implemented
    • Inherited parent class
    • All constructors
    • All methods
    • All Feild
    • annotation
    package Reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    //Get class information
    public class Demo02 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
            Class c1 = Class.forName("Reflection.User");
    
            //You can also use objects
            //User user = new User();
            //c1 = user.getClass();
    
            //Get the name of the class
            System.out.println(c1.getName());//Get package name + class name
            System.out.println(c1.getSimpleName());//Get class name
    
            System.out.println("=================================");
    
            //Get the properties of the class
            Field[] fields = c1.getFields();//Only public properties can be found
    
            fields = c1.getDeclaredFields();//All attributes can be found
            for (Field field : fields) {
                System.out.println(field);
            }
    
            //Gets the value of the specified property
            Field name = c1.getDeclaredField("name");
            System.out.println(name);
    
            System.out.println("======================================");
    
            //Method to get class
            Method[] methods = c1.getMethods();//Get all the methods of this class and its parent class
            for (Method method : methods) {
                System.out.println("natural:" + method);
            }
    
            methods = c1.getDeclaredMethods();//Get all methods of this class
            for (Method method : methods) {
                System.out.println("getDeclaredMethods: " + method);
            }
    
            System.out.println("============================================");
    
            //Get the specified method
            //If overloading is involved, parameters are required
            Method getName = c1.getMethod("getName", null);
            Method setName = c1.getMethod("setName", String.class);
            System.out.println(getName);
            System.out.println(setName);
    
            System.out.println("============================================");
    
            //Gets the specified constructor
            Constructor[] constructors = c1.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("natural:" + constructor);
            }
    
            constructors = c1.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("getDeclaredConstructors:" + constructor);
            }
    
            //Gets the specified constructor
            Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
            System.out.println("appoint:" + declaredConstructor);
    
        }
    }
    
  • In practice, the operation code for obtaining class information is not often developed

  • Be familiar with Java Function of lang.reflect package and reflection mechanism

  • How to get the names and modifiers of attributes, methods and constructors

Dynamically create object execution methods

Call the specified method

  • Through reflection, the Method in the class is called and completed through the Method class
    • Get a Method object through the getMethod(String name, Class... parameterTypes) Method of Class class and set the parameter type required for the operation of this Method
    • Then use Object invoke(Object obj, Object[] args) to call and pass the parameter information of the set obj object to the method
      • Object corresponds to the return value of the original method. If the original method has no return value, null is returned
      • If the original method is a static method, the formal parameter Object obj can be null at this time
      • If the original method parameter list is empty, Object[] args is null
      • If the original method is declared as private, you need to explicitly call the setAccessible(true) method of the method object before calling the invoke() method to access the private method

setAccessible

  • Method, Field and Constructor objects all have setAccessible() methods

  • setAccessible is a switch that enables and disables access security checks.

  • If the parameter value is true, it indicates that the Java language access check should be cancelled when the reflected object is used.

    • Improve the efficiency of reflection. If reflection must be used in the code, and the code of this sentence needs to be called frequently, please set it to true
    • So that private members that cannot be accessed can also be accessed
  • If the parameter value is false, it indicates that the reflected object should implement Java language access check

  • Performance comparison and analysis

package Reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//Analyze performance issues
public class Test {

    //Normal mode call
    public static void test01(){
        User user = new User();

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        
        long endTime = System.currentTimeMillis();

        System.out.println("1 billion times in ordinary way:" + (endTime - startTime) + "ms" );

    }

    //Reflection mode call
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();

        System.out.println("1 billion times in reflection mode:" + (endTime - startTime) + "ms" );

    }

    //Reflection mode call off detection
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();

        System.out.println("Turn off the reflection mode after detection for 1 billion times:" + (endTime - startTime) + "ms" );

    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        test01();
        test02();
        test03();
    }
}

Reflection operation generics

  • Java uses the mechanism of generic erasure to introduce generics. Generics in Java are only used by the compiler javac to ensure the security of data and avoid the problem of forced type conversion. However, once the compilation is completed, all types related to generics are erased

  • In order to manipulate these types through reflection, Java has added parameterizedtype and genericarraytype

  • TypeVariable and WildcardType are several types to represent types that cannot be classified into Class but have the same name as the original type

  • ParameterizedType: indicates a parameterized type, such as Collection

  • GenericArrayType: indicates that an element type is an array of parameterized types or type variables. TypeVariable: is the public parent interface of various type variables

  • WildcardType: represents a wildcard type expression

    package Reflection;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;
    import java.util.Map;
    
    //Get generics through reflection
    public class Demo04 {
    
        public void test01(Map<String,User> map, List<User>list){
            System.out.println("test01");
        }
    
        public Map<String, User> test02(){
            System.out.println("test02");
            return null;
        }
    
        public static void main(String[] args) throws NoSuchMethodException {
            Method method = Demo04.class.getMethod("test01", Map.class, List.class);
    
            Type[] genericParameterTypes = method.getGenericParameterTypes();
            for (Type genericParameterType : genericParameterTypes) {
                System.out.println("#" + genericParameterType);
                if (genericParameterType instanceof ParameterizedType){
                    Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                    for (Type actualTypeArgument : actualTypeArguments) {
                        System.out.println(actualTypeArgument);
                    }
                }
            }
    
            method = Demo04.class.getMethod("test02",null);
            Type genericReturnType = method.getGenericReturnType();
    
            if (genericReturnType instanceof ParameterizedType){
                Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
    
    }
    

Reflection operation annotation

  • getAnnotations

  • getAnnotation

    package Reflection;
    
    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    
    //Practice reflection
    public class Demo05 {
    
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
            Class c1 = Class.forName("Reflection.Student2");
    
            //Get annotations through reflection
            Annotation[] annotations = c1.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
    
            //Get the value of annotation value
            Tablezy tablezy = (Tablezy)c1.getAnnotation(Tablezy.class);
            String value = tablezy.value();
            System.out.println(value);
    
            //Gets the annotation specified by the class
            Field f = c1.getDeclaredField("name");
            Fieldzy annotation = f.getAnnotation(Fieldzy.class);
            System.out.println(annotation.columName());
            System.out.println(annotation.type());
            System.out.println(annotation.length());
    
            
    
        }
    }
    
    @Tablezy("db_student")
    class Student2{
    
        @Fieldzy(columName = "db_id", type = "int", length = 10)
        private int id;
        @Fieldzy(columName = "db_age", type = "int", length = 10)
        private  int age;
        @Fieldzy(columName = "db_name", type = "varchar", length = 3)
        private String name;
    
        public Student2() {
        }
    
        public Student2(int id, int age, String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student2{" +
                    "id=" + id +
                    ", age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    //Annotation of class name
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Tablezy{
        String value();
    }
    
    //Attribute annotation
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Fieldzy{
        String columName();
        String type();
        int length();
    }
    
    

note

Java annotation and reflection mechanism md network disk link
Extraction code: ryvd

Click jump crazy God to say
Video Explanation Java annotation and reflection mechanism

Keywords: Java Back-end

Added by falcon1 on Sun, 27 Feb 2022 16:29:49 +0200