[untitled] annotation and reflection

Posted by hhheng on Fri, 10 Dec 2021 11:45:19 +0100

Annotation and reflection

Annotation

  • annotation effect
    • It is not the procedure itself, which can be explained
    • It can be read by other programs (such as compiler, etc.)
  • Format of annotation
    • The annotation exists in the code as "@ annotation name", and some parameter values can be added
  • 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

Built in annotation

  • @Override: defined in Java In lang. override, this annotation is only applicable to rhetoric, indicating that one 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, classes, and representations. Programmers are not encouraged to use such elements, usually because it is dangerous or there are better choices
  • @SuppressWarnings: defined in Java Lang. SuppressWarnings, used to suppress warnings at compile time
package annotation;

public class Test01 extends Object{

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

    //@Deprecated does not encourage programmers to use it, but it can be used, usually because it is dangerous or there are better choices
    @Deprecated
    public static void test(){
        System.out.println("Deprecated");
    }
    
    public static void main(String[] args) {
        test();
    }
}

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 lock support are in Java You can find (@ Target, @ Retention, @ Documented, @ Inherited) in lang.annotation package
    • @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)
    • @Documented: indicates that the annotation will be included in the javadoc
    • @Inherited: indicates that the subclass can inherit the annotation in the parent class
package annotation;

//Test meta annotation
import java.lang.annotation.*;

@MyAnnotation
public class Test02 {
    public void test(){
    }
}
//Target indicates where our annotation can be used
@Target(value = {ElementType.METHOD,ElementType.TYPE})

//@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)
@Retention(value = RetentionPolicy.RUNTIME)

//@Documented: indicates that the annotation will be included in the javadoc
@Documented

//@Inherited: indicates that the subclass can inherit the annotation in the parent class
@Inherited

//Define an annotation
@interface MyAnnotation{

}

Custom annotation

  • When you use @ interface to customize annotations, you automatically inherit Java 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
    • Annotation elements must have values. When defining annotation elements, we often use the null character, 0 as the default value
package annotation;

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 = 22)
    public void test2(){}

    @MyAnnotation3("Cheng Jin Zeng")
    public void test3(){}
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    //Annotated parameters: parameter type + parameter value ();
    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 {"Tsinghua University","Peking University"};
}

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

Reflection mechanism

  • 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 with the help of the Reflection API during execution, and can directly operate the direct 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. We see the structure of the Class through the mirror. Therefore, we call it reflection

    Normal method: import the required "package class" name - > instantiate through new - > obtain the instantiated object

    Reflection method: instantiate the object - > getClass () method - > get the complete "package class" name

Static language VS dynamic language

  • Dynamic language 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. The main dynamic languages are: Object-C, c#, JavaScript, PHP, Python, etc
  • Static language corresponds to dynamic language. The main static languages are Java, C and C++
  • Java can be called quasi dynamic language, that is, Java has certain dynamics. We can use reflection mechanism to obtain characteristics similar to dynamic language

Get reflection object

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
  • Processing annotations at run time
  • Generate dynamic proxy
  • Wait······

Advantages and disadvantages of Java reflection

  • Advantages: 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
package annotation.reflection;

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

        Class c2 = Class.forName("annotation.reflection.User");
        Class c3 = Class.forName("annotation.reflection.User");
        Class c4 = Class.forName("annotation.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(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
    }
}

//Entity class: pojo, entity
class User{
    private String name;
    private int age;
    private int id;

    public User() {
    }

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

    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 getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

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

Class class

  • Class itself is also a class
  • Class 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

[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-mazymzuy-163913241573) (C: \ users \ ZCJ \ desktop \ screenshot \ QQ screenshot. png)]

Get an instance of Class

  • 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;
    
  • If an instance of a Class is known, call the getClass() method of the instance to obtain the Class object

    Class clazz = Person.getClass();
    
  • 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");
    
package annotation.reflection;

//What are the ways to create the test class
public class Test02 {
    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("annotation.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";
    }
}

Class objects of all types

package annotation.reflection;

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;    //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);

        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

Class loading process: when a program actively uses a class, if the class has not been loaded into memory, the system will initialize the class through the following three steps: class loading - > class link - > class initialization

Class loading and ClassLoader analysis:

  • Class Load: read the class file of the class into memory and create a Java. Net file for it Lang. class object. This is done by the class loader
  • Class Link: merge the binary data of the class into the JRE
    • 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 class 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)
  • Class initialization: the JVM is responsible for initializing the class
    • The process of executing a class constructor () method. The class constructor () method is generated by the combination of the assignment action of all variables in the class automatically collected at compile time and the static code block statement. (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 locked and synchronized correctly in a multithreaded environment.
package annotation.reflection;

public class Test05 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
        /*
        1.When loaded into memory, a Class object corresponding to a 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
                  }
               m=100;
         */
    }
}

class A{
    static {
        System.out.println("A Class static code block initialization");
        int m = 300;
    }

    static int m = 100;

    public A(){
        System.out.println("A Class");
    }
}

Analysis class initialization

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
    • 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
  • Passive reference of class
    • When accessing a static domain, only the class that actually declares the domain will be initialized. For example, when the static variable of the parent class is referenced through the 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)
package annotation.reflection;

public class Test06 {
    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("annotation.reflection.Son");

        //A method that does not generate a reference to a class
        //System.out.println(Son.a);

        //Son[] array = new Son[5];

        System.out.println(Son.D);
    }
}

class Father{
    static int a = 1;
    static {
        System.out.println("The parent class is loaded");
    }
}

class Son extends Father{
    static int b = 1;
    static {
        System.out.println("Subclass loaded");
    }

    static int c = 3;
    static final int D = 4;
}

Class loader

  • The function of the class loader: load the bytecode file contents of the class file into memory, convert these static data into the runtime data structure of the method area, and then generate a java.lang.Class object representing this class in the heap as the access entry to the class data in the method area
  • Class caching: the standard JavaSE 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

The JVM defines the following three types of Loaders

  • Boot class 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. This loader cannot be obtained directly
  • Extension class loader: it is responsible for packaging the jar package under jre/lib/ext directory or the jar package under the directory specified by - D java.ext.dirs into the working library
  • System class loader: it is responsible for packing classes and jar s in the directory indicated by Java classpath or - Djava.class.path. It is the most common loader
package annotation.reflection;

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

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

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

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

        //Test which loader loads the JDK built-in classes
        ClassLoader classLoader1 = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader1);

    }
}

Get the runtime structure of the class

package annotation.reflection;

import com.sun.media.sound.SoftTuning;

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

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

        //Get the name of the class (User class)
        System.out.println(c1.getName());//Get package name + 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 obtained

        fields = c1.getDeclaredFields();//Find all properties
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("=====================");
        //Gets the value of the specified property
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

        System.out.println("=====================");
        //Method to get class
        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);
        }

        System.out.println("=======================");
        //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);

        System.out.println("========================");
        //Gets the specified constructor
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        constructors = c1.getConstructors();
        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("appoint:"+declaredConstructor);
    }
}

Dynamically create object execution methods

What can I do with a class object?

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

Thinking: can't you create an object without a parameterless constructor? You can instantiate the operation only after explicitly calling the constructor of the class and passing in the parameters

  • The steps are as follows:
    • Get the constructor of this Class through getdeclaraedconstructor (Class... parameterTypes) of Class
    • Pass an object array into the formal parameters of the constructor, which contains all the parameters required by the constructor
    • Instantiate objects through Constructor

Call the specified method:

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

  • 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
  • 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, tut 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
  • If the parameter value is true, it indicates that the Java language scope check should be cancelled when the reflected object is used
    • Improve the efficiency of reflection. If reflection must be used in the code, and the code of this sentence needs to be called frequently, please set it to true
    • Access using a private member that is not otherwise accessible
  • If the parameter value is false, it indicates that the reflected object should implement Java language access check
package annotation.reflection;

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

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

        //Create an object through the constructor
        //Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        //User user = (User)constructor.newInstance("Zeng Chengjin", 007, 22);
        //System.out.println(user);

        //Call normal methods through reflection
        User user2 = (User)c1.newInstance();
        //Get a common method through reflection
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke: activate
        //(object, "value of method")
        setName.invoke(user2,"Cheng Jin Zeng");
        System.out.println(user2.getName());

        //Operation properties by reflection
        User user3 = (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(user3,"Cheng Jin Zeng");
        System.out.println(name);
    }
}

Performance comparison and analysis

package annotation.reflection;

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

//Performance comparison and analysis
public class Test10 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test01();
        test02();
        test03();
    }
    //Normal method 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 with common methods:"+(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 detection and execute 1 billion times:"+(endTime-startTime)+"ms");
    }
}

Get generic information

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 the problem of 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 has added parametrizdetype, GenericArrayType, TypeVariable and WildcardType to represent types that cannot be classified into Class but have the same name as the original type
  • Parametrizdetype: 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 expression
package annotation.reflection;

import sun.nio.cs.ext.MacArabic;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

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

Get annotation information

Reflection operation annotation

  • getAnnotation
  • getAnnotations
package annotation.reflection;

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

public class Test12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("annotation.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
        Tablezeng tablezeng = (Tablezeng) c1.getAnnotation(Tablezeng.class);
        String value = tablezeng.value();
        System.out.println(value);

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

    }
}

@Tablezeng("db_student")
class Student2{
    @Fieldzeng(columnName = "db_id",type = "int",length = 10)
    private int di;
    @Fieldzeng(columnName = "db_age",type = "int",length = 10)
    private int age;
    @Fieldzeng(columnName = "db_name",type = "varchar",length = 3)
    private String name;

    public Student2() {
    }

    public Student2(int di, int age, String name) {
        this.di = di;
        this.age = age;
        this.name = name;
    }

    public int getDi() {
        return di;
    }

    public void setDi(int di) {
        this.di = di;
    }

    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{" +
                "di=" + di +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

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

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

Topics: Java jar intellij-idea