Annotation and reflection

Annotation and reflection

1.1 notes

Function of Annotation

  • It is not the procedure itself, which can be explained
  • It can be read by other programs (such as compiler, etc.)

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

@Deprecated : this comment can be used to modify methods, attributes and classes, indicating that programmers are not encouraged to use such elements. Usually, it is dangerous or there is a better choice.

@SuppressWarnings("all"): used to suppress compile time warnings all the time

example:

import java.util.ArrayList;
import java.util.List;

//What is annotation
public class Test01 extends Object{


    //@Override 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") //Suppression warning
    public void test02(){
        List list = new ArrayList();
    }


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

1.2 meta annotation

The function of meta annotation is to annotate other annotations.

example:

//Test meta annotation

import java.lang.annotation.*;

public class Test02 {
}

//Define an annotation
//Target indicates where our annotations 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{

}

1.3. User defined annotation

use @interface Custom annotation

example:

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 {
    //Annotations can display assignments. If there is no default value, we must assign a value to the annotation
    @MyAnnotation2(age =18,name = "ss")
    public void test(){

    }

    @MyAnnotation3("ss")
    public void test1(){

    }

}

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

    String[] schools() default {"Hubei University","Zhixing College"};

}

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

1.4 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

Advantages and disadvantages of reflection

advantage:

It can dynamically create objects and compile, reflecting great flexibility

Disadvantages:

Impact on Performance

example:

//What is reflection
public class Test02 {

    public static void main(String[] args) throws ClassNotFoundException {
        //Gets the Class object of the Class through reflection
        Class c1 = Class.forName("com.ss.reflection.User");
        System.out.println(c1);

        Class c2 = Class.forName("com.ss.reflection.User");
        Class c3 = Class.forName("com.ss.reflection.User");
        Class c4 = Class.forName("com.ss.reflection.User");
        
        //A Class is loaded in memory with only one Class object
        //After a class is loaded, the whole structure of the class will be encapsulated in the Cla 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 +
                '}';
    }
}

1.5 common methods of Class

[the external chain 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-jh9benyu-1627644107765) (C: \ users \ 2239871144 \ appdata \ roaming \ typora \ typora user images \ image-20210513105252194. PNG)]

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 has the highest program performance

Class clazz = Person.class;

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

Class clazz = person.getClass();

3. The full Class name of a Class is known. Under the path of cutting the Class, it can be obtained through the static method forName() of Class class, and ClassNotException may be thrown

Class clazz = Class.forName("demo01.Student");

4. The built-in basic data type can directly use the class name Type 5. You can also use ClassLoader

5. You can also use ClassLoader

example:

//What are the creation methods of test Class
public class Test03 {
    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("com.ss.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{
    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";
    }
}

Summary

import java.lang.annotation.ElementType;

//Class of all types
public class Test04 {
    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 the same Class
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());


    }
}

1.6. Extension class loader

  • Class loading

    When a program wants to use a class, if the class has not been loaded into memory, the system will initialize the class through three steps: loading, connecting and initialization

    • load

      This is to read the class file into memory and create a class object for it. When any class is used, the system will create a class object

    • connect

      Verify whether there is a correct internal structure and is consistent with other classes

      Preparation is responsible for allocating memory for static members of the class and setting default initialization values

      The process of resolving the symbolic reference (constant name) in the virtual machine constant pool and replacing it with a direct reference (address)

    • initialization

      The JVM initializes classes

      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 first

      Virtual chance ensures that the () methods of a class are properly locked and synchronized in a multithreaded environment

  • Class loading process

    • Create an instance of a class
    • Class, or assign a value to a static variable
    • Class
    • Use reflection to force the creation of Java. Net corresponding to a class or interface Lang.class object
    • Initializes a subclass of a class
    • Directly use Java Exe command to run a main class
  • Class loader

    Be responsible for The Class file is loaded into the intrinsic and the corresponding Class object is generated for it

  • Composition of class loader

    • System ClassLoader

      It is responsible for loading the class file from the java command, as well as the jar package and classpath specified by the classpath environment variable when the JVM starts

    • Extension ClassLoader extension classloader

      Be responsible for loading jar packages in JRE's extension directory, and the ext directory under JRE's lib directory in JDK

    • Bootstrap ClassLoader root classloader

      Also known as boot class loader, it is responsible for loading Java core classes and is written in C + +

example:

public class Test07 {
    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 the current class is
        ClassLoader classLoader = Class.forName("com.ss.reflection.Test07").getClassLoader();
        System.out.println(classLoader);

        //Test who loaded the JDK built-in class
        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"));
    }
}

1.7. Get the complete construction of runtime class

Get the complete structure of the runtime class through reflection

Field,Method,Constructor,Superclass,Interface,Annotation

example:

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

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

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

        //Get the properties of the class
        System.out.println("===============");

        Field[] fields = c1.getFields();//Only public properties can be found

        fields  = c1.getDeclaredFields();//All properties 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);

        //Method to get class
        System.out.println("=================");
        Method[] methods = c1.getMethods();
        for (Method method :methods) {
            System.out.println("natural:"+method);
        }
        methods = c1.getDeclaredMethods();
        for (Method method :methods) {
            System.out.println("getDeclaredMethods:"+method);
        }


        //Gets the specified method
        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();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
         constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

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

1.8. Create objects dynamically through reflection

example:

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


//Dynamically create objects through reflection
    public class Test09 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
            //Get class object
            Class c1 = Class.forName("com.ss.reflection.User");

            //Construct an object
            //User user = (User) c1.newInstance();//  The essence is to call the parameterless constructor of the class
//           System.out.println(user);

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

            //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,"ss");
            System.out.println(user3.getName());

            //Operation properties by reflection
            System.out.println("=====================");
            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 properties or methods
            name.setAccessible(true);
            
            name.set(user4,"ss");
            System.out.println(user4.getName());
        }
    }


1.9 performance comparison between ordinary mode call and reflection mode call

setAccessible

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

//Analyze performance issues
public class Test10 {


    //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, turn 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("Close the detection mode for 1 billion times:"+(endTime-startTime)+"ms");


    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Test01();
        Test02();
        Test03();
    }

}

2.0 reflection operation generics

example:

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 Test11 {

    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 = 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 = Test11.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);
            }
        }


    }
}

2.1. Reflection operation notes

getAnnotations

getAnnotation

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("com.ss.reflection.Student2");

        //Get annotations through reflection
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //Gets the value of the annotation
        Tabless tabless = (Tabless)c1.getAnnotation(Tabless.class);
        String value = tabless.value();
        System.out.println(value);

        //Gets the annotation specified by the class
        Field f = c1.getDeclaredField("id");
        Filedss annotation = f.getAnnotation(Filedss.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());



    }
}

@Tabless("db_student")
class Student2{
    @Filedss(columnName = " db_id",type = "int",length = 10)
    private int id;
    @Filedss(columnName = " db_age",type = "int",length = 10)
    private int age;
    @Filedss(columnName = " 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;
    }

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

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

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

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

Keywords: Java

Added by heminfotech on Sun, 02 Jan 2022 07:29:27 +0200