Java reflection mechanism

annotation

built-in annotation

meta annotation


@Target indicates where our annotations can be used
@Retention indicates where our annotations are still valid
@Documented indicates whether to generate our annotations in JAVAdoc
@inherited subclasses can inherit parent class annotations

custom annotation

Annotations can be customized through @interface, which automatically inherits the java.lang.annotation.Annotation interface

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

public class test02 {
    
    @MyAnnotation(name="mao")
    public void test()
    {
        
    }
}
//scoped on classes and methods
@Target({ElementType.TYPE, ElementType.METHOD})
//valid at runtime
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    //Annotated parameters: parameter type + parameter name ()
    String name() default "";
}

reflection mechanism

Reflection (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 by means of the Reflection API during execution, and can directly manipulate the internal properties and methods of any object.
**Advantages of reflection: ** Objects can be dynamically created and compiled, showing great flexibility
**Disadvantages of reflection:** Has an impact on performance. Using reflection is basically an interpretation operation, telling the JVM what we need, and then it helps us achieve it, this type of operation is always slower than performing the same type of operation directly.

Class class

When we create a class in java, the JVM will automatically create a Class object of this class to store various information of the class

Several ways to get class objects

        //1. Obtained through the class attribute of the class
        Class c1=Student.class;
        //2. Obtained through the getClass() method of the object
        Class c2= new Student().getClass();
        //3. Obtained by forName
        Class c3=Class.forName("com.mao.pojo.Student");

Java memory analysis

class loader

The role of the class loader: load the content of the class bytecode file into the memory (that is, load the class into the memory), convert these static data into the running data structure of the method area, and then generate a representation of the class in the heap The java.lang.Class file is used as the access entry of the class in the method area
Class cache: The standard JavaSE class loader can look up classes as required. Once a class is loaded into the class loader, it will maintain (cache) load for a period of time. However, the garbage collection mechanism of the JVM can recycle these Class objects

Class loading and understanding of ClassLoader

Class loading process:
When a program actively uses a certain class, if the class has not been loaded into the class loader, the system will go through three steps:

Create an object of the runtime class

import com.mao.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

public class exercise1_test {

    @Test
    public void testSpring01() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c=Class.forName("com.mao.pojo.Student");
        //Get the name of the class
        System.out.println(c.getName());
        System.out.println(c.getSimpleName());
        //Get the attributes of the class (only public)
        Field[] fields = c.getFields();
        for (Field field:fields)
        {
            System.out.println(field);
        }
        //Get the attributes of the class (not public can also be obtained)
        Field field = c.getDeclaredField("name");
        System.out.println(field);
        //get class method
        Method[] methods = c.getMethods();//Get all methods of this class and parent class
        Method[] declaredMethods = c.getDeclaredMethods();//Get all methods of this class
        Method getName = c.getMethod("getName", null);//Get specified method
        
        //get constructor
        Constructor[] constructors = c.getConstructors();
        //Get the specified constructor (get the constructor with all parameters)
        Constructor constructor = c.getConstructor(String.class, int.class, String.class);
    }
}

Dynamically create objects and manipulate

import com.mao.pojo.User;
import org.junit.Test;

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

/**
 * Dynamically create object execution method
 */
public class Reflection_test {
    @Test
    public void testUser() throws Exception
    {
        //get class object
        Class c = Class.forName("com.mao.pojo.User");
        //Construct an object based on the obtained class object
        User user = (User)c.newInstance();

        //Dynamically call methods through reflection mechanism
        Method method=c.getDeclaredMethod("setName",String.class);
        //invoke( object, "parameters of the method")
        method.invoke(user,"mao");
        System.out.println(user.getName());

        //Manipulating attributes through reflection
        Field name = c.getDeclaredField("name");
        //Private properties cannot be directly manipulated, and security monitoring of properties or methods needs to be turned off
        name.setAccessible(true);
        name.set(user,"maomao");
        System.out.println(user.getName());
    }
}

Manipulating generics through reflection

Obtain annotation information through reflection

		Test02 t=new Test02();
        Class c1 = t.getClass();
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation:annotations)
        {
            System.out.println(annotation);
        }

        //Get the value of the value in the annotation
        MyAnnotation annotation = (MyAnnotation)c1.getAnnotation(MyAnnotation.class);
        String value=annotation.value();
        System.out.println(value);

Tags: Java jvm programming language

Posted by mattdarnold on Thu, 12 Jan 2023 09:51:02 +1030