Collation of annotation related knowledge points of Java

Posted by jamesm87 on Sun, 23 Jan 2022 21:12:38 +0100

Predefined annotations in JDK

@override: check whether the annotated method inherits from the parent class (Interface)

@Deprecated: the content of this annotation indicates that it is obsolete

@SuppressWarnings: suppress warnings

//Suppress all warnings that may pop up in the current class are suppressed
@SuppressWarnings("all")
public class stu
{
    String name;
    //All warnings for the current method are suppressed
    @SuppressWarnings("all")
        public void show()
        {
            System.out.println("Student's name:"+name);
        }
}

Custom annotation

Format:

Meta annotation
public @interface Annotation name()
{
   Attribute list;
}

Essence: Annotation is an interface, which inherits the Annotation interface by default

Properties: abstract methods in interfaces

requirement:

The return type of the property consists of the following values:

  • Basic data type
  • String
  • enumeration
  • annotation
  • Arrays of the above types

The attribute is defined, and it needs to be assigned a value when it is used

  • If the default keyword is used to initialize the default value when defining an attribute, the attribute can not be assigned when annotation is used
  • If only one attribute needs to be assigned and the name of the attribute is value, value can be omitted and the value can be defined directly
  • When assigning an array value, the value is wrapped with {}. If there is only one value in the array, {} can be omitted

demonstration

Custom annotation class:

package reflect;

public @interface annto {
    int age();
    String name();
     Per p();
     ann2 anno2();

     String[] strs();
}

stu class:

package reflect;
@annto(age=18,name="Huyou ",p=Per.perople,anno2=@ann2,strs={"Huyou ","children"})
public class stu
{
    String name;
        public void show()
        {
            System.out.println("Student's name:"+name);
        }
}

Meta annotations: annotations that describe annotations

@Target: describes where the annotation can work

ElementType value:

  1. TYPE: can act on a class
  2. METHOD: can act on methods
  3. FIELD: can act on member variables
//value can be omitted. The following writing method can act on classes, methods and member variables at the same time
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
//@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
public @interface ann2 {
}

@Retention: describes the stage in which annotations are retained

//The annotation currently described will be retained in the bytecode file and read by the JVM
@Retention(RetentionPolicy.RUNTIME)

@Documented: describes whether annotations are extracted into api documents

@Inherited: describes whether the annotation is inherited by subclasses'

@Inherited
public @interface ann2 {
}

For the class or member method annotated with ann2 below, its subclasses will also be annotated with ann2

Use (parse) annotations in the program: get the attribute values defined in the annotations

Gets the object (class, method, field) of the annotation definition location

Gets the specified annotation

getAnnotation(class)
//In fact, it is to generate a subclass implementation object of the annotation interface in memory
public class ProImp1 implements ann2
{
   public String ClassName()
   {
   return "reflect.stu";
   }
   public String MethodName()
   {
     return "show";
    }
}

Call the abstract method in the annotation to obtain the configured property value

demonstration:

Requirements: do not change any code of the class, create any object of the class, and execute any method of the class

ann2 annotation class:

package reflect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ann2
{
 String ClassName();
 String MethodName();
}

stu class:

package reflect;

public class stu
{
    String name;
    public void show()
    {
        System.out.println("Student's name:"+name);
    }
}

main function:

package reflect;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
@ann2(ClassName = "reflect.stu",MethodName = "show")
public class main {
    public static void main(String[] args) throws Exception
    {

        //1. Get the bytecode file object of this class
        Class<main>  mainClass=main.class;
        //2. Get the annotation object above
        ann2 a2=mainClass.getAnnotation(ann2.class);
        //In fact, it is to generate a subclass implementation object of the annotation interface in memory
/*        public class ProImp1 implements ann2
        {
            public String ClassName()
            {
                return "reflect.stu";
            }
            public String MethodName()
            {
                return "show";
            }
        }*/
        //3. Call the abstract method defined in the annotation object to obtain the return value
        String className=a2.ClassName();
        String methodName=a2.MethodName();
        //3. Load this class into memory
        Class cls=Class.forName(className);
        //4. Create object
        Object obj=cls.newInstance();
        //5. Get method object
        Method method=cls.getMethod(methodName);
       //6. Implementation method
        method.invoke(obj);
    }
}

Simple test framework

main:

package reflect;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
/*
*  After the main method is executed, it will automatically execute all the detected methods (Methods annotated with check). If the method has exceptions, the exceptions will be recorded in the file
* */
public class checkTest {
    public static void main(String[] args) throws IOException {
      //1. Create a computer object
        calculator c=new calculator();
        //2. Get bytecode file object
        Class cls=c.getClass();
        //3. Get all methods
        Method[] methods=cls.getDeclaredMethods();

        //Record the number of exceptions
        int number=0;
        BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
        for(Method method:methods)
        {
            //4. Judge whether there is a check comment on the method
            if(method.isAnnotationPresent(check.class))
            {
                //5. Yes, implementation
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    //6. Catch exception
                    //Record to file
                    number++;
                    bw.write(method.getName()+"The method is abnormal");
                    bw.newLine();
                    bw.write("The name of the exception:"+e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("Cause of abnormality"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("------------------------------------------");
                    bw.newLine();
                }
            }
        }
        bw.write("A total of"+number+"Secondary anomaly");
        bw.flush();
        bw.close();
    }
}

calculator:

package reflect;
public class calculator {
    @check
   public  void add()
    {
        System.out.println("a+b=Huyou ");
    }
    @check
    public void minus()
    {
        System.out.println("1/0="+1/0);
    }
    @check
    public  void div()
    {
        String str=null;
        str.toString();
    }

}

check:

package reflect;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/*You need to add @ Retention(RetentionPolicy.RUNTIME) to the custom annotation to declare that the annotation's survival policy can be retained until runtime, and then it can be obtained correctly through reflection.*/
@Retention(RetentionPolicy.RUNTIME)
public @interface check {
}

Test results:

bug.txt:

minus The method is abnormal
 Name of exception:ArithmeticException
 Cause of abnormality/ by zero
------------------------------------------
div The method is abnormal
 Name of exception:NullPointerException
 Cause of abnormality Cannot invoke "String.toString()" because "str" is null
------------------------------------------
There were 2 exceptions in this test