It's time to test the real technology! After reading, I will teach you to really understand Java annotation and reflection!


Annotation and reflection

java.Annotation

1. What is annotation

  • Annotation is from jdk5 New technologies introduced from 0
  • Function of Annotation:
    • It is not the procedure itself, which can be explained. (this is no different from comment s.)
    • It can be read by other programs (such as compiler, etc.).
  • Format of Annotation:
    • Annotations exist in the code as "@ annotation name". You can also add some parameter values, such as @ 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.
//Test learning what is annotation
public class Test01 extends Object{
    //@Override overridden annotation
    @Override
    public String toString() {
        return super.toString();
    }
}

2. Built in annotation

  • @Override: defined in Java In lang. override, this annotation is only applicable to the next method, indicating that a 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 class representations. Chen Xuyuan uses such an element because it is dangerous or there is a better choice.
  • @SuppressWarnings: defined in Java Used to suppress warnings in. Warnings when compiling.
    • Different from the previous two comments, you need to add a parameter to use correctly. These parameters are defined by Bauhinia. We can use them selectively.
      • @SuppressWarning("all")
      • @SuppressWarning("unchecked")
      • @SuppressWarning("value={"unchecked","desprecation"})
      • Wait
//Test learning what is annotation
public class Test01 extends Object{
    //@Override overridden annotation
    @Override
    public String toString() {
        return super.toString();
    }

    //@Deprecated is not recommended for programmers, but it can be used, or there is a better way
    @Deprecated
    public static void test(){
        System.out.println("@Deprecated");
    }

    @SuppressWarnings("all")
    public void test02(){
        List list = new ArrayList();
    }

    public static void main(String[] args) {
        test();
    }
}

3. Meta annotation

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

  • These types and the classes he supports are in Java You can find it in the lang.annotation package. (@Target,@Retention,@Document,@Inherited)

    • @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 the javadoc
    • @Inherited: indicates that the subclass can inherit the annotation in the parent class
import java.lang.annotation.*;

//Test meta annotation
@MyAnnotation
public class Test02 {

    @MyAnnotation
    public void test(){

    }
}

//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 > source
@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{

}

4. User defined annotation

  • When you use * * @ interface * * to customize annotations, java.java.java is automatically inherited lang.annotation. Annotation interface
  • analysis:
    • @Interface is used to declare an annotation. Format: public @interface annotation name {definition content}
    • Each of these methods 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
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//Custom annotation
public class Test03 {
    //Annotation can display assignment. If there is no default value, we must assign assignment to annotation display
//    @MyAnnotation2(name = "Zhang San")
    @MyAnnotation2(schools = {"University of Electronic Science and technology","Chengdu University of Information Engineering"})
    public void test(){

    }
    //When there is only one value, value can be omitted=
    @MyAnnotation3("Zhang San")
    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();
}

@interface MyAnnotation3{
    String value();
}

5. Reflection mechanism

Back to the top

Static VS dynamic language

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, runtime structure cannot be changed, and language 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.

Back to the top

Java Reflection

  • Reflection is the key to Java being regarded as a dynamic language. Reflection mechanism allows programs 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, a Class object is generated in the method area of heap memory (a Class has only one Class object), which contains the complete Class structure information. 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 vividly call it reflection

Back to the top

Functions provided by Java 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 run time
  • Call the member variables and methods of any object at run time
  • Process comments at run time
  • Generate dynamic proxy
  • ...

Back to the top

Advantages and disadvantages of Java reflection

advantage:

  • It can dynamically create objects and compile, reflecting great flexibility

Disadvantages:

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

Back to the top

Main API s related to reflection

  • java.lang.Class: represents a class
  • java.lang.reflect.Method: represents the method of the class
  • java.lang.reflect.Field: represents the member variable of the class
  • java.lang.reflect.Constructor: represents the constructor of the class
  • ...

Back to the top

Class class

The following methods are defined in the Object class, which will be 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

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 retains an object of the same Class type. A Class object contains information about a specific structure (Class / interface / enum / annotation / primitive type / void).

  • Class itself is also a class
  • Clas objects can only be created by the system
  • A loaded Class has only one Class instance in the JVM
  • A class object corresponds to a class 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

Common methods of Class

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, structure, array Class, or void) represented by this 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[] getConstructors()Returns an array containing some Constructor objects
Method getMethod(String name,Class...T)Returns a Method object whose formal parameter type is paramType
Field[] getDeclaredFields()Returns an array of Field objects

Get an instance of Class

  1. If a specific class is known, it is obtained through the class attribute of the class. This method is the most safe and reliable, and the program performance is the highest.

Class clazz = Person.class;

  1. If the instance of a Class is known, call the getClass() method of the instance to obtain the Class object.

Class clazz = person.getClass();

  1. 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")

  1. The built - in basic data type can use the class name directly Type
  2. You can also use ClassLoader
//What are the creation methods of test Class
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("This man 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.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: wrapper 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{
    String name;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.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

import java.lang.annotation.ElementType;

//All types of class es
public class Test03 {
    public static void main(String[] args) {
        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = Override.class;
        Class c6 = ElementType.class;
        Class c7 = Integer.class;
        Class c8 = void.class;
        Class c9 = 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);

        //The secondary element type is the same class as the dimension
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
    }
}

Class load memory analysis

Understanding of class loading and ClassLoader

  • 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. Net 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
    • Preparation: the stage of formally allocating memory for class variables (static) and setting the default initial value of variables. These memory will be allocated in the method area
    • 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 automatically collecting the assignment actions of all class variables in the class at compile time and combining the statements in the static code block. (the class constructor is used to construct class information, not the constructor to construct the class object.).
    • When initializing a class, if it is found that its parent class has not been initialized, the initialization of its parent class needs to be triggered.
    • Virtual opportunity ensures that a class constructor () method is properly locked and synchronized in a multithreaded environment.
/*
    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;
        }
 */
public class Test04 {
    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");
    }
}

When does class initialization occur?

  • Active reference of class (class initialization must 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)
//When will the test class initialize
public class Test05 {
    static {
        System.out.println("main Class is loaded");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        //1. Active reference
//        Son son = new Son();
        //Reflection also produces active references
//        Class.forName("Reflection.Son");

        //A method that does not generate a reference to a class
//        System.out.println(Son.b);
        //Son[] array = new Son[3];
        System.out.println(Son.M);
    }
}

class Father{
    static int b = 2;
    static {
        System.out.println("The parent class is 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 role of the class loader: 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. Java. Java.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.

Class loader is used to load classes into memory. The JVM specification defines loaders for classes of the following types.

  • Boot loader: written in C + +, it is the class loader of the JVM. It is responsible for the core library of the Java platform and is used to load the core class library. The loader cannot get directly.
  • Extension class loader: it is responsible for the jar package or - D Java under jre/lib/ext directory The jar in the directory specified by ext.dirs is packaged into the working library.
  • System class loader: responsible for java -classpath or - D Java class. The classes and jar s in the directory referred to in path are packaged into the work, which is the most commonly used loader.

public class Test06 {
    public static void main(String[] args) throws ClassNotFoundException {

        //Gets the loader of the system class
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        //Gets the parent class loader -- > extension class loader of the system class loader
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        //Get the parent class loader -- > root loader of the extension class loader (C/C + +)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        //Test which loader loads the current class
        ClassLoader classLoader = Class.forName("Reflection.Test06").getClassLoader();
        System.out.println(classLoader);

        //Test who loaded the JDK built-in class
        ClassLoader classLoader2 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader2);

        //How can I get the path of the system loader
        String property = System.getProperty("java.class.path");
        System.out.println(property);

        //How many times do parents delegate
            //java.lang.String --> 
        /*
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;
        C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;
        C:\Users\Tohka\IdeaProjects\JavaSE\out\production\Basic grammar;
        C:\Users\Tohka\IdeaProjects\JavaSE\Basic syntax \ SRC \ com \ lib \ commons-io-2.8.0 jar;
        D:\Program Files\JetBrains\IntelliJ IDEA 2020.2.3\lib\idea_rt.jar
         */
    }
}

Back to the top

Create an object for the runtime class

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 construction methods
  • All methods
  • All fields
  • annotation
  • ...
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//Get class information
public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("Reflection.User");

        User user = new User();
        c1 = user.getClass();
        //Get the name of the class
        System.out.println(c1.getName());   //Get package name plus 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
//        for (Field field : fields) {
//            System.out.println(field);
//        }
        Field[] declaredFields = c1.getDeclaredFields();   // All properties found
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
//        Field name = c1.getField("name");    // Only public properties can be found
//        System.out.println(name);

        //Gets the value of the specified property
        Field name = c1.getDeclaredField("name");    //Only public properties can be found
        System.out.println(name);

        //Method to get class
        System.out.println("==========================");
        Method[] methods = c1.getMethods();                //Get all public methods of this class and its parent class
        Method[] declaredMethods = c1.getDeclaredMethods();   //Get all methods of this class
        for (Method method : methods) {
            System.out.println("natural" + method);
        }
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        //Gets the specified method
        //heavy load
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        //Gets the specified constructor
        System.out.println("===================");
        Constructor[] constructors = c1.getConstructors();      //Get public method
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();      //Get all methods
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("#" + declaredConstructor);
        }

        //Gets the specified constructor
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println("appoint:" + declaredConstructor);

    }
}

Dynamically create object execution methods

What can I do with a Class object?

  • Create Class object: call newInstance() method of Class object
    • 1) Class must have a parameterless constructor.
    • 2) The constructor of the class needs sufficient access rights

**Thinking** Can't you create an object without a parameterless constructor? As long as the constructor in the class is explicitly called during the operation and the parameters are passed in, the operation can be instantiated.

  • The steps are as follows:
    • 1) Get the constructor of the specified parameter type of this Class through getdeclaraedconstructor (Class... parameterTypes) of Class class
    • 2) You want to pass an object array into the formal parameters of the constructor, which contains all the parameters required by the constructor.
    • 3) Instantiate objects through Constructor

Call the specified method

Through reflection, the Method in the class is called and completed through the Method class.

  1. Get a Method object through the getMethod(String name, Class... parameterTypes) Method of Class class, and set the parameter type required for this Method operation.

  2. Then use Object invoke(Object obj, Object[] args) to call and pass the parameter information of the obj object to be set to the method.

Object invoke(Object obj, Object ... args)

  • 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
  • If the original method parameter list is empty, Object[] args is null
  • If the original method is declared as private, you need to display the setAccessible(true) method of the calling 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 guidance is used.
    • Improve the efficiency of reflection. If reflection must be used in the code, and the code needs to be called frequently, set it to true.
    • Make the 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.
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //Get Class object
        Class c1 = Class.forName("Reflection.User");

        //Construct an object
        User user = (User) c1.newInstance();   //Essentially, it calls the class's parameterless constructor
        System.out.println(user);

        //Creating objects through constructors
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user1 = (User) constructor.newInstance("Zhang San", 001, 18);
        System.out.println(user1);

        //Call normal methods through reflection
        User user3 = (User) c1.newInstance();
        //Get a method by reflection
        Method setName = c1.getDeclaredMethod("setName", String.class);

        //invoke: Activate
        //(object, "value of method")
        setName.invoke(user3,"Li Si");
        System.out.println(user3.getName());

        //Operation properties by reflection
        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");

        //Private properties cannot be operated directly. We need to turn off the security detection of the program and setAccessible(true) of the property or method
        name.setAccessible(true);
        name.set(user4, "Wang Wu");
        System.out.println(user4.getName());
    }
}

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

//Analyze performance issues
public class Test09 {
    //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("The common method is executed one billion times:" + (EndTime - StartTime));
    }

    //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("The reflection method is executed one billion times:" + (EndTime - StartTime));
    }

    //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("Reflection method off detection is executed one billion times:" + (EndTime - StartTime));
    }

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

Back to the top

Reflection operation generics

  • Java uses the generic erasure mechanism to introduce generics. Generics in Java are only used by the compiler javac to ensure data security and avoid 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 adds ParameterizedType, GenericArrayType, TypeVariable and WildcardType to represent types that cannot be normalized to the Class class but have the same name as the original type. [white whoring data]
  • ParameterizedType: represents a parameterized type, such as Collection
  • GenericArrayType: indicates that an element type is a parameterized type or an array type of type variable
  • TypeVariable: it is the public parent interface of various types of variables
  • WildcardType: represents a wildcard type representation
//Get generics through reflection
public class Test11 {
    public void test01(Map<String, User> map, List<User> list){
        System.out.println("test01");
    }join Java Development and exchange sample: 484138291 blowing water and chatting together
    public Map<String, User> test02(){
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test11.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 method2 = Test11.class.getMethod("test02", null);
        Type genericReturnType = method2.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }
}

Back to the top

Reflection operation annotation

  • getAnnotations
  • getAnnotation

Back to the top

Exercise: ORM

  • What is ORM?

    • Object relationship mapping -- > object relationship mapping

    • Correspondence between class and table structure

    • Attribute and field correspondence

    • Object and record correspondence

  • Requirement: use annotation and reflection to complete the mapping relationship between class and table structure

import java.lang.annotation.*;
import java.lang.reflect.Field;

//Practice reflection operation annotation
public class Test12 {
    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);
        }

        //Gets the value of the annotated value
        TableZhang tablezhang = (TableZhang) c1.getAnnotation(TableZhang.class);
        String value = tablezhang.value();
        System.out.println(value);
        join Java Development and exchange sample: 484138291 blowing water and chatting together
        //Gets the annotation specified by the class
        Field f = c1.getDeclaredField("name");
        FieldZhang annotion = f.getAnnotation(FieldZhang.class);
        System.out.println(annotion.columName());
        System.out.println(annotion.type());
        System.out.println(annotion.length());
    }
}

@TableZhang("db_student")
class student2{
    @FieldZhang(columName = "db_id", type = "int", length = 10)
    private int id;
    @FieldZhang(columName = "db_age", type = "int", length = 10)
    private int age;
    @FieldZhang(columName = "db_name", type = "varchar", length = 3)
    private String name;

    @Override
    public String toString() {
        return "student2{" +
                "id=" + id +
                ", age=" + age +
                ", 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;
    }

    public String getName() {
        return name;
    }

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

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

    public student2() {
    }
}

//Annotation of class name
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableZhang{
    String value();

}

//Attribute annotation
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldZhang{
    String columName();
    String type();
    int length();
}

Classification: Java Foundation

Many dry goods collected in 2021 include mysql, netty, spring, threads, spring cloud, jvm, source code, algorithm and other detailed explanations. Friends who need to obtain these contents add Q sample: 484138291

Keywords: Java Back-end Software development

Added by automatix on Sat, 15 Jan 2022 03:51:24 +0200