Annotation and reflection

annotation

  • Annotation is from jdk5 New technologies introduced from 0
  • Function of Annotation:
    • It is not the procedure itself, which can be explained
    • Can be read by other programs
  • Format of Annotation:
    • The annotation exists in the code with the @ annotation name, and some parameter values can be added.
  • Where Annotation is used:
    • It can be attached to package, class, method, field, etc., which is equivalent to adding additional auxiliary information to them. You can access these metadata through reflection mechanism programming

Built in annotation

@Override

This comment applies only to rhetorical devices, indicating that one method declaration intends to override another method declaration in the superclass

//@Override overridden annotation
@Override
public String toString(){
    return super.toString();
}

@Deprecated

Magnetic beads 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

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

Used to suppress compile time warnings. Parameters need to be added

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

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: used to describe the applicable scope of the annotation
    • @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 javadoczhong
    • @Inherited: indicates that the subclass can inherit the annotation in the parent class
//Where can we use the Target annotation
@Target(value = ElementType.METHOD)
//Retention indicates where the annotation is valid
@Retention(value = RetentionPolicy.RUNTIME)
//Documented indicates whether annotations are generated in Javadoc
@Documented
//The Inherited subclass can inherit the annotation of the parent class
@Inherited
@interface MyAnnotation{}//Define an annotation

Custom annotation

package Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//Custom annotation


@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    //Annotated parameters: parameter type + parameter name (default) "default";
    String name() default "";
    int age() default 0;
    int id() default -1;// If the default value is - 1, it means it does not exist
    String[] schooles();
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    String value();//When there is only one parameter and its name is value, you can pass the parameter directly without writing the parameter name
}
public class Test03 {
    //The annotation can display the assignment. If there is no default value, the annotation must be assigned
    @MyAnnotation2(schooles = "Luo Shi")
    public void test1(){}

    @MyAnnotation3("value")
    public void test2(){}
}

reflex

Static & dynamic

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 "quasi dynamic language" That is, Java is dynamic to some extent. We can use reflection mechanism to obtain characteristics similar to dynamic language The dynamic nature of Java makes programming more flexible

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, an object of Class type is generated in the method area of heap memory (a Class has only one Class object), and this object contains the complete Class structure We can see the structure of the Class through this object This object is like a mirror, through which you can see the structure of the Class, so it is called 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 and disadvantages of reflection

Advantages: it can dynamically create objects and compile, reflecting great flexibility

**Disadvantages: * * affects the performance Using reflection is basically an interpretive operation that tells the JVM what we want to do and it meets our requirements This type of operation is always slower than performing the same operation directly

Reflection get class

package Reflection;

//What is reflection
public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //Get the class object of the class through reflection
        Class user = 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(user);
    }
}
//Entity class
class User{
    private String name;
    private int id;
    private String pwd;

    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 String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

Class class

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/interface/enum/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 a class file loaded into the JVM
  • 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 load and run dynamically, you have to obtain the corresponding class object first

common method

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-mvvrzeko-1623026682221) (Note 1.png)]

Get the method of Class

  • Given the specific class, this method is the most safe and reliable and the program performance is the highest through the class attribute of the class

    Class c=Person.class

  • Given an instance of a Class, call getClass()fangfa of the instance to get the Class object

    Class c = person.getClass()

  • The full Class name of a Class is known, and the Class can be obtained through the static method forName() of Class under the Class path,

    Class c = Class.forName("demo01.Student")

  • The built-in basic data type can use the class name directly Type

Class loading mechanism

The JVM loads the class file into memory, verifies, prepares, parses and initializes the data, and finally forms a Java type process that can be directly used by the JVM.

1. Loading

Load the class bytecode file into memory, convert these data into runtime data (static variables, static code blocks, constant pools, etc.) in the method area, and generate a class object in the heap to represent this class (reflection principle) as the access entry of class data in the method area.

2. Link

Merge the binary code of the Java class 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 variables) and setting the initial value of class variables. These memory will be allocated in the method area. Note that the setting initial value is the default value at this time, and the specific assignment is completed in the initialization stage.
• parsing
The process of replacing symbolic references in the virtual machine constant pool with direct references (address references).

3. Initialize

The initialization phase is the process of executing class constructor () methods. The class constructor () method is generated by the combination of the assignment actions of all class variables in the class automatically collected by the compiler and the statements in * * static statement block) * *.

  • When initializing a class, if you find that its parent class has not been initialized, you need to initialize its parent class first.
  • Virtual chance ensures that the () methods of a class are locked and synchronized correctly in a multithreaded environment.

Class reference

1. Active reference (must be initialized)

  • 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 the virtual machine starts, java Hello will initialize the Hello class. To put it bluntly, start the class where the main method is located first.
  • When initializing a class, if its parent class is not initialized, its parent class will be initialized first

2. Passive reference

  • When accessing a static domain, only the class that actually declares the domain will be initialized. For example, referencing a static variable of a parent class through a subclass will not cause subclass initialization.
  • 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 at the compilation stage).
public class Demo02 {
    public static void main(String[] args) throws ClassNotFoundException {
        //Active reference: new is an object of a class
//        People people = new People();
        //Active reference: static members of the calling class (except final constants) and static methods
//        People.getAge();
//        System.out.println(People.age);
        //Active invocation: using Java The method of lang.reflect package makes reflection calls to the class
//        Class.forName("pri.xiaowd.classloader.People");


        //Passive reference: when accessing a static domain, only the class that actually declares the domain will be initialized.
//        System.out.println(WhitePeople.age);
        //Passive reference: a reference is defined through an array and will not be initialized
//        People[] people = new People[10];
        //Passive reference: reference constants do not trigger the initialization of this class
        System.out.println(People.num);
    }
    //Active call: start the class where the main method is located first
//    static {
//        System. out. Println ("the class where the main method is located is loaded when the virtual machine is started");
//    }
}

class People{
    static int age = 3;
    static final int num = 20;
    static {
        System.out.println("People Initialized!");
    }
    public People() {
    }
    public static int getAge() {
        return age;
    }
    public static void setAge(int age) {
        People.age = age;
    }
}

class WhitePeople extends People{
    static {
        System.out.println("WhitePeople Initialized!");
    }
}

Class loader

1. Class cache

The standard Java SE Class loader can find classes as required. Once a Class is loaded into the Class loader, it will be loaded (cached) for a period of time. However, the JVM garbage collector can recycle these Class objects.

2. Classification of class loaders

bootstrap class loader
(1) It is used to load the core library of Java (java_home / JRE / lib / rt.jar, the content under the sun.boot.class.path path path). It is implemented in native code (C language) and does not inherit from Java lang.ClassLoader.
(2) Load the extension class and application class loader. And specify their parent class loader.

extensions class loader
(1) The extension library used to load Java (JAVA_HOME/jre/ext/*.jar, or the content under the java.ext.dirs path). The implementation of Java virtual machine will provide an extension library directory. Find the Java class loader in this directory and load it.
(2) By sun misc. Launcher $extclassloader implementation.

application class loader
(1) It loads Java classes according to the class path of the Java application (classpath, the content under the java.class.path path path). Generally speaking, Java application classes are loaded by it.
(2) By sun misc. Launcher $appclassloader implementation.

Custom class loader
(1) Developers can inherit Java Lang. classloader class implements its own class loader to meet some special needs.

3,java.class.ClassLoader class

(1) Function:

  • java. The basic responsibility of lang. classloader class is to find or generate the corresponding bytecode according to the name of a specified class, and then define a Java class from these bytecodes, that is, Java An instance of lang.class class.
  • ClassLoader is also responsible for loading the resources required by Java applications, such as image files and configuration files.
    (2) Common methods:
  • getParent() returns the parent loader of this class loader.
  • loadClass(String name) loads a class named name, and the returned result is Java An instance of the lang.class class.
    This method is responsible for loading the class with the specified name. First, it will look for it from the loaded class. If it is not found; Load from parent ClassLoader[ExtClassLoader]; If it is not loaded into, try to load it from Bootstrap ClassLoader (findbootstrap classornull method). If it still fails to load, load it yourself. If it cannot be loaded, an exception ClassNotFoundException is thrown.
  • findClass(String name) finds a class named name, and the returned result is Java An instance of the lang.class class.
  • findLoadedClass(String name) finds the loaded class with name, and the returned result is Java An instance of the lang.class class.
  • defineClass(String name, byte[] b, int off, int len) converts the contents of byte array b into Java class, and the returned result is Java An instance of the lang.class class. This method is declared final.
  • Resolveclass (class <? > C) links the specified Java class.

Gets the structure of the class

package Reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//Get class information
public class Test02 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class user = Class.forName("Reflection.User");

        //Get the name of the class
        System.out.println(user.getName()); //Get package name + class name
        System.out.println(user.getSimpleName());//Get class name

        //Get the properties of the class
        System.out.println("=============================");
        Field[] fields = user.getFields();//Only public properties can be found
        for (Field field : fields) {
            System.out.println(field);
        }
        fields = user.getDeclaredFields();//Find all properties
        for (Field field : fields) {
            System.out.println(field);
        }

        //Field name = user.getField("name");// The specified public property was found
        Field name = user.getDeclaredField("name");//The specified property was found
        System.out.println(name);

        //Method to get class
        System.out.println("=============================");
        Method[] methods = user.getMethods();//Get all public methods of this class and its parent class
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("=============================");
        methods = user.getDeclaredMethods();//Get all methods of this class
        for (Method method : methods) {
            System.out.println(method);
        }
        //Gets the specified method
        //Methods may be overloaded, so you need to pass in parameters
        Method getName = user.getMethod("getName", null);
        Method setId = user.getMethod("setId", int.class);
        System.out.println(getName);
        System.out.println(setId);
        
    }
}
package Reflection;

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

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

        //Construct an object
        /*User u1 = (User)cu.newInstance();//The essence is to call the parameterless construction of the class
        System.out.println(u1);*/

        //Creating objects through constructors
        /*Constructor constructor = cu.getConstructor(String.class, int.class, String.class);
        User u2 = (User) constructor.newInstance("Li Si ", 1," 123 ");
        System.out.println(u2);*/

        //Call normal methods through reflection
        User u3 =(User) cu.newInstance();
        //Get a method by reflection
        Method setName = cu.getMethod("setName", String.class);
        //Invoke (object, "value of method"): Activate
        setName.invoke(u3,"lisa");

        //Operation properties by reflection
        //You cannot directly operate private properties. You need to turn off the security detection of the program and setAccessible() of properties or methods
        Field id = cu.getDeclaredField("id");
        id.setAccessible(true);//
        id.set(u3,5);
        System.out.println(u3);
    }
}

Get comments

package Reflection;

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


public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("Reflection.Student");

        //Get annotations through reflection
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
            //Gets the value of the annotation
            ClassAnnnotation classAnnnotation = (ClassAnnnotation) annotation;
            System.out.println(classAnnnotation.value());
        }

        //Gets the specified annotation
        Field name = c1.getDeclaredField("name");
        FieldAnnotation annotation = name.getAnnotation(FieldAnnotation.class);
        System.out.println(annotation.length());
        System.out.println(annotation.name());
        System.out.println(annotation.type());
    }
}

@ClassAnnnotation("db_student")
class Student{
    @FieldAnnotation(name="db_name",type = "String",length = 10)
    private String name;
    @FieldAnnotation(name="db_age",type = "int",length = 3)
    private int age;
    @FieldAnnotation(name="db_grade",type = "int",length = 3)
    private int grade;

    public Student() {
    }

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

    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;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", grade=" + grade +
                '}';
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnnnotation{
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation{
    String name();
    String type();
    int length();
}

        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", grade=" + grade +
                '}';
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnnnotation{
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation{
    String name();
    String type();
    int length();
}

Keywords: Java

Added by Hitman2oo2 on Mon, 31 Jan 2022 11:05:54 +0200