Explain the use of JDK annotations and the method of customizing annotations with examples

  • 2021-07-03 00:03:59
  • OfStack

Three Basic Annotations in JDK

a, @ Override: Check that the subclass is indeed a method that overrides the parent class.
b, @ Deprecated: The explanation is out of date.
c, @ SuppressWarnings ({"unused", "deprecation"}): Suppress warnings in programs. Type of unused warning. {} Array. all suppresses all warnings.

Easy to use:


public class Demo1 {
  //@SuppressWarnings({ "deprecation", "unused" })
  @SuppressWarnings("all")
  public void fun()
  {
    int i = 5;
    System.out.println("hello");
    System.out.println(new Date().toLocaleString());
  }
}
class Tests extends Demo1
{
  @Override
  public void fun()
  {
    super.fun();
  } 
  @Deprecated
  public void tt()
  {
    System.out.println(new Date().toLocaleString());
  }
}

Declare 1 annotation @ interface annotation name {}


public @interface MyAnnotation{}

Note that its essence is an interface, which needs to inherit the Annotation interface.


public interface MyAnnotation extends java.lang.annotation.Annotation {
}

Attribute type of annotation:

1. Basic types 2.String 3. Enumeration type 4. Annotation type 5. Class type 6. 1-dimensional array types of the above types

How to define it specifically, let's look at the code:


public @interface MyAnno1 {
  // All the attributes defined in the annotation are attributes 
  int age() default 20;
  String[] name() default "hehe";
  String value() default "haha";
  Love love();
  //MyAnno2 anno();
  //public static final int num = 5;// Yes 
  //public abstract void fun();//error
}

Use custom annotations:


public class Demo2 {
  //@MyAnno1(age=25,name={"jack","lucy"},value="zhengzhi")
  //@MyAnno1(value="zhengzhi")
  @MyAnno1(value="zhengzhi",love=Love.eat)
  public void tests()
  {
  }
}

If we use custom annotations without default values, we need to set the values of the attributes in the annotations.

Reflection of annotation: (soul)


 Simulation Junit Adj. @Test
a Reflection annotation class 
java.lang.reflect.AnnotatedElement:
<T extends Annotation> T getAnnotation(Class<T> annotationType): Gets an annotation reference of the specified type. Not returned null . 
Annotation[] getAnnotations() Gets all the annotations, including those inherited from the parent class. 
Annotation[] getDeclaredAnnotations() : Get your own annotations. 
boolean isAnnotationPresent(Class<? extends Annotation> annotationType) Determines whether the specified annotation exists. 
Class , Method , Field , Constructor And so on AnnotatedElement Interface .
 If: Class.isAnnotationPresent(MyTest.class): Determine if there is any on the class @MyTest Annotation; 
Method.isAnnotationPresent(MyTest.class): Is there a judgment method on it @MyTest Annotations. 

Below through the code to achieve 1.

We simulated the functionality of @ Test annotations

First of all, this is our annotation @ MyTest


import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// Meta-annotation:   Used to annotate annotations 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
  long timeout() default Integer.MAX_VALUE;// That sets the timeout time 
}

This is the class where we use annotations:


public class DBCRUD {
  @MyTest(timeout=1000000)
  public void addTest()
  {
    System.out.println("addTest Method executes the ");
  }
  @MyTest
  public void updateTest()
  {
    System.out.println("updateTest Method executes the ");
  }
}

When we use annotations, we need to determine whether the class uses annotations, which we do through reflection.


private static void method1() throws IllegalAccessException,
    InvocationTargetException, InstantiationException {
    Class claz = DBCRUD.class;// Get the ByteCode File Object 
    // Get all the methods in this class and its parent class 
    Method[] methods = claz.getMethods();
    for(Method m:methods){
      // Determine whether the method is used @MyTest This annotation 
//     boolean boo = m.isAnnotationPresent(MyTest.class);
//     System.out.println(m.getName()+"===="+boo);// It's all false  Default annotations survive to  CLASS , change survives until RUNTIME
      if(m.isAnnotationPresent(MyTest.class)){
        m.invoke(claz.newInstance(), null);
      }
    }
  }

What we need to note here is that we need to consider the survival scope of custom annotations.

The default custom annotation only survives until compile time, class stage.

Note that the @ Retention annotation is applied to our custom annotation above, which changes the survival scope of the custom annotation.

This annotation is also called meta-annotation, and annotations that can only be used on annotations are called meta-annotations.

The above method method does not consider the problem of timeout, so let's improve it again.


//method1();
    // Reflect the properties of parsing annotations 
    Class claz = DBCRUD.class;
    Method[] methods = claz.getMethods();
    for(Method m:methods){
      // Obtain from this method MyTest Annotation 
      MyTest mt = m.getAnnotation(MyTest.class);
      if(mt!=null){
        // Get the attributes in the annotation 
        long out = mt.timeout();
        long start = System.nanoTime();
        m.invoke(claz.newInstance(), null);
        long end = System.nanoTime();
        if((end-start)>out)
        {
          System.out.println(" Running timeout ");
        }
      }
    }

Summarize


Related articles: