java annotations and reflection

Keywords: Java

Crazy God learning notes on this site

1, Annotation

1. What is annotation

Annotation is a concept introduced from JDK 5.0

eg: @ override overriding annotation

  • 1. It is not the procedure itself that explains the procedure ()
  • 2. It can be read by other programs
  • Not necessary
  • 3. Format: @ comment + comment name, and some parameter values can be added
  • 4. It has the function of inspection and restraint
  • It can be placed on methods or classes, etc

... annotations are for people, annotations are for people and machines

2. Built in annotation

@Override indicates that the method declaration is intended to override the method declaration in the supertype.
@Deprecated obsolete deprecated code
@SuppressWarnings suppress warnings (can be put in parameters)

3. Meta annotation

Role: responsible for annotation and other annotations
Four standard meta annotation types:

  • @Where can the annotation described by Target be used
@Target(value =ElementType.METHOD)  Explain that the scope is on the method 
@Target(ElementType.FIELD) Scope on property (member variable)
@Target(value ={ElementType.METHOD,ElementType.TYPE})  Explain that the scope is on methods and classes 

  • @Retention indicates the level at which annotation information needs to be saved (usually RUNTIME)
    Indicates where our comments are still valid
@Retention(value =RetentionPolicy.RUNTIME)
  • @Documented is our annotation generated in JAVAdoc
  • @Inherited indicates that the subclass can inherit the annotation from the parent class

4. User defined annotation

  • When using @ interface to customize annotations, the annotation interface is automatically inherited
  • Parameter format written in the annotation: parameter type + parameter name ();
  • Default set default
    The annotation shows the assignment. If there is no default value, we must assign it
@interface MyAnnotion{
string name() default ""
int id() default -1   //Generally, negative one represents nonexistence
}

@interface MyAnnotion2{
string value()
}

@MyAnnotion2("abc")  //When there is only one and the name is value, it is equivalent to (value="'abc '")
public viod test(){
}

2, Reflection

1. Concept

Java (static language) is regarded as the key of quasi 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. private can also be operated

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

Normal method: introduce the required "package class" name 1 > instantiate through new - > obtain the instantiated object
Reflection method: instantiate object I > getClass method - > get the complete "package class" name

2. Creation method of class

public class test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person =new Student();
        System.out.println("This person is:"+person.name);
        //Obtained by object
        Class c1 = person.getClass();
        //forname get
        Class c2 = Class.forName("lesson05.Student");
        //Obtained by class name. Class
        Class c3 = Student.class;
        
        //Get parent type
        Class c5 = c1.getSuperclass();
    }

    
    
}

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

3. Which types have Class objects

public class test04 {
    public static void main(String[] args) {
        Class objectClass = Object.class;//class
        Class comparableClass = Comparable.class;//Interface
        Class aClass = String[].class;//One dimensional array
        Class aClass1 = int[][].class; //Two dimensional array
        Class overrideClass = Override.class;//annotation
        Class elementTypeClass = ElementType.class; //enumeration
        Class  integerClass = Integer.class;//Basic data type
        Class voidClass = void.class;//void
        Class classClass = Class.class;//Class
    }
}

4. Analysis class initialization

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

  • Use the methods of the java.lang.reflect package to make reflection calls to the class

  • When initializing a class, if its parent class is not initialized, its parent class will be initialized first
    (2.) 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

  • The reference constant (final) will not trigger the initialization of this class (constants are stored in the constant pool of the calling class in the link phase)

    public class test05 {
        public static void main(String[] args) throws ClassNotFoundException {
            System.out.println("main call");
    
            //(1.) active reference of class (class initialization must occur)
            ///zi son = new zi();
    
            //System.out.println(Fu.b);
    
    
          // Class.forName("lesson05.zi");
            //Class.forName("lesson05.Fu");
    
            //(2.) passive reference of class (class initialization will not occur)
    
            //System.out.println(zi.b);
    
            //zi[] zis = new zi[5];
    
    
            //System.out.println(zi.m);
    
    
        }
    
    }
    class Fu {
        static int b=2;
        static {
            System.out.println("Parent class called");
        }
    }
    class zi extends Fu{
       final static int m=0;
        static {
            System.out.println("Subclass called");
        }
    }
    

Supplement:

1.static method

Static methods are generally called static methods. Because static methods can be accessed without relying on any object, there is no this for static methods, because they do not depend on any object. Since there are no objects, there is no this. Moreover, due to this feature, non static member variables and non static member methods of the class cannot be accessed in static methods, because non static member methods / variables must rely on specific objects to be called.

However, it should be noted that although non static member methods and non static member variables cannot be accessed in static methods, static member methods / variables can be accessed in non static member methods.

2.static variable

Static variables are also called static variables. The difference between static variables and non static variables is that static variables are shared by all objects and have only one copy in memory. It will be initialized when and only when the class is first loaded. Non static variables are owned by objects. They are initialized when creating objects. There are multiple copies, and the copies owned by each object do not affect each other.

static member variables are initialized in the defined order.

3.static code block

Static keyword also plays a key role in forming static code blocks to optimize program performance. Static blocks can be placed anywhere in the class, and there can be multiple static blocks in the class. When the class is first loaded, each static block is executed in the order of static blocks, and only once.

4.static is used on member variables to indicate that only one copy is saved. final is used to ensure that variables are immutable

5. Class loading memory analysis

Test code:

Operation results:

analysis:

Note: the order in which static code blocks and static variables are executed depends on the order in which the code is written, and is completed at

6. Class loader

  • bootstrap class loader
bootstrap class loader :use C++Written by, yes JVM Self contained class
 Loader, responsible for Java Platform core library( rt.jar),Used to load core classes
 Library. The loader cannot get it directly
  • extensions class loader
extensions class loader :be responsible for jre/ib/ext Under directory jar Package or-
D java.ext.dirs Specified directory jar Package into work warehouse
  • system class loader
system class loader :be responsible for java - classpath or-D
java.class. path The class under the directory and jar Packaging entry
 As a library, it is the most commonly used loader

7. Get the complete structure of the runtime class

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

//Get class information
public class test06 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        USer uSer = new USer();
        Class c1 = uSer.getClass();
        //Gets the name of the class
        System.out.println(c1.getName());

//        //Get the properties of the class
//        System.out.println("===========================================");
//        Field[] fields = c1.getFields(); / / only public attributes can be found
//        for (Field field : fields) {
//            System.out.println(field);
//        }
//        System.out.println("===========================================");
//        Field [] Fields1 = C1. Getdeclaraedfields(); / / find all attributes
//        for (Field field : fields1) {
//            System.out.println(field);

        //Gets the specified attribute
            System.out.println("===========================================");
            System.out.println(c1.getDeclaredField("name"));

        //Method to get class
            System.out.println("===========================================");
            Method[] methods = c1.getMethods();  //All methods of this class and its parent class
        
            for (Method method : methods) {
                System.out.println("natural:"+method);
            }
            System.out.println("===========================================");
            Method[] declaredMethods = c1.getDeclaredMethods();//All methods of this class
        
            for (Method declaredMethod : declaredMethods) {
                System.out.println("getDeclaredMethods Of:"+declaredMethod);
        }
        //Gets the specified method
        //Overloading may occur, so you need to throw in a type for the incoming parameter
            System.out.println("===========================================");
            Method getName = c1.getMethod("getName", null);
            Method setName = c1.getMethod("setName", String.class);
            System.out.println(getName);
            System.out.println(setName);
        
        //Construction method
            System.out.println("===========================================");
            Constructor[] constructors = c1.getConstructors();//public constructor of this class
        
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }

            System.out.println("===========================================");
            Constructor[] constructors1 = c1.getDeclaredConstructors(); //All construction methods of this class
        
            for (Constructor constructor1 : constructors1) {
                System.out.println(constructor1);
            }

        //Gets the specified constructor
            System.out.println("===========================================");
            System.out.println(c1.getConstructor(String.class, int.class, int.class));


    }
}

7. Dynamically create object execution methods

null if there are no parameters

//Create objects dynamically through reflection
public class test07 {
    public static void main(String[] args) throws Exception {
        //Get class object
        Class c1 = Class.forName("lesson05.USer");

        //Construction object
        USer user = (USer) c1.newInstance();//Essentially called a parameterless constructor
        System.out.println(user);

        //Creating objects through constructors
        Constructor constructor = c1.getConstructor(String.class, int.class, int.class);
        USer user2  = (USer) constructor.newInstance("dongGEi", 01, 18);
        System.out.println(user2);

        //Call normal methods through reflection
        USer user3 = (USer) c1.newInstance();
        //Method of obtaining by reflection
        Method setName = c1.getMethod("setName", String.class);
        setName.invoke(user3,"abcd"); //Activate invoke and give user3 the object parameter abcd
        System.out.println(user3);
        //Operation properties by reflection
        USer user4 = (USer) c1.newInstance();
        Field name = c1.getDeclaredField("name");
            //Private properties cannot be operated directly. You need to turn off security detection first. Both properties and methods are setAccessible(true)
        name.setAccessible(true);//Set permissions
        name.set(user4,"abcd222");
        System.out.println(user4);

    }
}

8. Performance comparison

  • The common method new User comes out to perform operations such as set and get
  • Reflect the method uesr.getClass and get the method invoke
  • Turn off the reflection call of permission detection and add a setAccessible (true)

Normal speed > turn off reflection for permission detection > reflection method

When reflection is needed, permission detection can be turned off to improve speed

9. Get generic information by reflection

Explain the above code: test01 is a method with Map and List parameters,

Reflection takes this method and gets the parameter list

Traverse the parameter list, and then strongly convert the parameter type that is a parameterized type (plus < >; generic type) to a parameterized type

Then traverse to get the true parameters

(colloquialism is a little windy =. =)

10. Get annotation information by reflection

ORM object relational 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

Look below before you look at psvm

package test;

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

public class Test {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> c1 = Class.forName("test.Student");
        //Get annotations through reflection
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //Get the value of annotation value
        //Gets the class of the specified annotation passed into the annotation
        TableDong tableDong = c1.getAnnotation(TableDong.class);
        String value = tableDong.value();
        System.out.println(value);

        //Gets the specified attribute (member variable)
        Field f = c1.getDeclaredField("name");
        //Get the specified annotation on the attribute and take out the value of the annotation
        FieldDong fieldDong = f.getAnnotation(FieldDong.class);
        System.out.println(fieldDong.columName());
        System.out.println(fieldDong.length());
        System.out.println(fieldDong.type());
        System.out.println("---------------");

        f = c1.getDeclaredField("id");
        //Gets the specified annotation
        fieldDong = f.getAnnotation(FieldDong.class);
        System.out.println(fieldDong.columName());
        System.out.println(fieldDong.length());
        System.out.println(fieldDong.type());
    }
}
@TableDong("db_student")
class Student{
    @FieldDong(columName = "db_id",type = "varchar",length = 10)
    private String id;
    @FieldDong(columName = "db_age",type = "int",length = 3)
    private int age;
    @FieldDong(columName = "db_name",type = "varchar",length = 10)
    private String name;

    public Student() {
    }

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

    public String getId() {
        return id;
    }

    public void setId(String 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 "Student{" +
                "id='" + id + '\'' +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

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

//Attribute annotation
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldDong{
    String columName(); //Column name (not student name)
    String type();
    int length();
}

My blog
(I still don't understand the JVM in-depth part of this article. I'll learn more about it later -. -)

Posted by sriphp on Thu, 02 Dec 2021 10:56:03 -0800