Know the annotation

Annotations (annotations) is a kind of tags, add annotations to program is for the program to play on a tag, without, is equal to without any mark, later, javac compiler, development tools, and other application can through reflection to understand your classes and various elements on the presence of markup, see what’s in your program, Tags can be added to packages, classes, attributes, methods, method parameters, and local variables.

Classification of action:

1. Document: Generate documentation using comments identified in the code.

2. Code analysis: Analyzing code through annotations identified in the code [using reflection]

3. Compiler checking: Allows the compiler to perform basic compiler checking with an annotation identified in the code.

Predefined annotations in the JDK

Three annotations provided internally after JDK1.5:

  • “Deprecated” means “obsolete”.
  • Override means “overwrite”
  • SuppressWarnings is used to suppress the compiler from generating warnings.

Let’s introduce each of them in turn.

@Deprecated

The show1() method is outdated and has fallen out of date with the requirements, so we type a @deprecated annotation on it. Show2 () is a more powerful feature.

    @Deprecated
    public void show1(a){
        // Found to be outdated, with functions not keeping up with requirements
    }

    public void show2(a){
        // A more powerful method
    }
Copy the code

We find a red line in the place of the call, which means that this method is deprecated and is not recommended. Since it is out of date, you can delete this method directly, but also to keep and tell you not to use, is not unnecessary? And the whole reason for doing this is to be backwards compatible, because if you delete it, then the old code would have to report errors whenever it referenced this method, so we need to do this to smooth the transition.

The getYear() method is also marked with a red line. This is also due to the @deprecated annotation. There are many such examples, the boys in the usual development pay attention to observe, expired methods do not use…

@Override

It is also easy to check whether the method being annotated is inherited from the superclass (interface). It avoids miswriting method names and parameters.

    @Override
    public String toString(a) {
        return "xxxx";
    }
Copy the code

@SuppressWarnings

The editor prompts us with a pink wavy line and tells us that variable ‘STR’ is never usedSo this is just one example, there are all kinds of warnings, and this is where we get really annoying, so what we can do is we can just say @suppresswarnings, tell the editor not to give me a warning, usually we pass all, @suppresswarnings (“all”), Now the wavy line is gone.

Of course, if we don’t want to suppress all of them, we can also suppress specific values if we want, as shown in the following table:

parameter instructions instructions
all to suppress all warnings Suppress all warnings
boxing to suppress warnings relative to boxing/unboxing operations Warning when suppressing packing and unpacking operations
cast to suppress warnings relative to cast operations Suppress map-related warnings
dep-ann to suppress warnings relative to deprecated annotation Suppress warnings to enable comments
deprecation to suppress warnings relative to deprecation Suppress expired method warnings
fallthrough to suppress warnings relative to missing breaks in switch statements Suppression is a warning missing in breaks in the switch
finally To suppress warnings relative to finally block that don’t return Suppress warnings that the finally module does not return
hiding to suppress warnings relative to locals that hide variable Suppress warnings associated with local variables of hidden variables
incomplete-switch to suppress warnings relative to missing entries in a switch statement Ignore that there is no complete switch statement
nls  to suppress warnings relative to non-nls string literals Ignore non-NLS characters
null  to suppress warnings relative to null analysis Ignore null operations
rawtypes  to suppress warnings relative to un-specific types when using generics on class params Ignore that no type is specified when using Generics
restriction  to suppress warnings relative to usage of discouraged or forbidden references Suppress warnings related to discouraging or disallowing the use of citations
serial  to suppress warnings relative to missing serialVersionUID field for a serializable class Ignore that the serialVersionUID variable is not declared in the SerialIZABLE class
static-access  to suppress warnings relative to incorrect static access Suppress incorrect static access mode warnings
synthetic-access  to suppress warnings relative to unoptimized access from inner classes Suppress warnings that subclasses do not have optimal access to inner classes
unchecked  to suppress warnings relative to unchecked operations Suppress warnings that no type check operation has been performed
unqualified-field-access  to suppress warnings relative to field access unqualified Warning to suppress unauthorized domains
unused  to suppress warnings relative to unused code   Warnings to suppress code that has not been used

Custom annotations

In addition to the JDK’s built-in annotations, we can also write custom annotations to meet some of our development needs, which is the focus of this article. The format for creating annotations is as follows:

/ / yuan note
public @interfaceAnnotation name {// Attribute list
}
Copy the code

The content of the custom Annotation decompiled, the Annotation is essentially an interface that inherits from the parent Annotation interface

public interface MyAnno extends java.lang.annotation.Annotation {}Copy the code

Here is an example of an annotation, which we will introduce in turn.

Yuan notes

Use another annotation class on top of an annotation class, and the annotation class being used is called a meta-annotation. The JDK provides us with four meta-annotations

@Retention

The @Retention annotation determines the lifecycle of the MyAnnotation annotation. It describes the phase to which the annotation is retained, SOURCE < CLASS < RUNTIME

  • SOURCE: Make the MyAnnotation annotation exist only in the Java SOURCE file, not when compiled to a.class file
  • CLASS: Make the MyAnnotation annotation exist in the Java source file (.java file), compile it into a.class file, and then the MyAnnotation annotation annotation does not exist when the CLASS identified by the MyAnnotation CLASS is loaded into memory by the CLASS loader
  • RUNTIME: Make the MyAnnotation annotation have a lifetime all the way to the RUNTIME of the application

@Target

The @Target meta-annotation determines which components an annotation can be identified on, such as a class, attribute, or method

  • Elementtype. TYPE: Can be applied to a class
  • Elementtype. METHOD: Can be applied to methods
  • Elementtype. FIELD: Can be applied to member variables

@Documented

Describes whether annotations are extracted into the JavaDoc API

@inherited

Describes whether annotations can be inherited by subclasses

attribute

As mentioned above, the essence of annotations is interfaces, so properties are abstract methods defined in interfaces.

Syntax: type attribute name (); The returned result must be of the following type:

  • Basic data type
  • Type String
  • Enumerated type
  • annotations
  • Arrays of the above types

In the figure above, a custom color property is used as follows:

// Apply the color property of the MyAnnotation annotation
@MyAnnotation(color = "red")
public class AnnotationTest {

    public static void main(String[] args) {
        // Use reflection mode to get the annotation corresponding instance object, in the object to call the corresponding property method
        MyAnnotation annotation = (MyAnnotation) AnnotationTest.class.getAnnotation(MyAnnotation.class);
        / / output redSystem.out.println(annotation.color()); }}Copy the code

Attribute assignment has some caveats

1. If you define a property using the default keyword to default the initial value of the property, you can use annotations without assigning a value

If the attribute is not assigned a value when the annotation is used, the default value will be used
String color(a) default "blue";
Copy the code

2. If an annotation has an attribute named value and you only want to set the value attribute (that is, all other attributes have default values or you only have one value attribute), omit the value= section.

 @SuppressWarnings("deprecation")
 @Retention(RetentionPolicy.RUNTIME)
 @Target( { ElementType.METHOD, ElementType.TYPE })
 public @interface MyAnnotation {
     String color(a) default "blue";// Specify the default value for the attribute
     String value(a);// Define an attribute named value
 }

 @MyAnnotation("xxx")// Use the equivalent of @myannotation (value=" XXX ")
Copy the code

When an array is assigned, the value is wrapped in {}. If there is only one value in the array, the {} can be omitted

// Attribute of array type
int[] arrayAttr() default {1.2.4};
// Use {}
@ MyAnnotation (arrayAttr = {2, four, five})
// If the array property has only one value, omit the braces for the property value
@MyAnnotation(arrayAttr=2).Copy the code

4, the enumeration

// Enumerates the attributes of the type
EumTrafficLamp lamp(a) default EumTrafficLamp.RED;
// Use annotations
@MyAnnotation(lamp=EumTrafficLamp.GREEN)
Copy the code

5. The attribute value of an annotation is another annotation

MetaAnnotation annotationAttr(a) default @MetaAnnotation("aaa");
Copy the code

Example of custom annotations

Let’s implement an annotation to create an object by reflection.

Custom notes:

/** * Custom annotation * the annotation surface executes which method in which class */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InvokAnno {

    String className(a);

    String methodName(a);

}
Copy the code

Define an entity class:

public class Person {

    public void show(a) {
        System.out.println("person show ...."); }}Copy the code

Create an object by reflection:

@InvokAnno(className = "com.jackxu.annotation.Person", methodName = "show")
public class InvokeTest {
    public static void main(String[] args) throws Exception {
        // Get the class object
        Class<InvokeTest> clazz = InvokeTest.class;
        // Get the annotation in the class object
        InvokAnno an = clazz.getAnnotation(InvokAnno.class);
        /** * the interface is the interface, the an is the implementation of the interface, The * public class MyInvokAnno implements InvokAnno {* * String className () {* return ". Com. Jackxu. An annotation Person "; * } * String methodName(){ * return "show"; *} *} */
        // Get the corresponding attribute in the annotation
        String className = an.className();
        String methodName = an.methodName();
        System.out.println(className);
        System.out.println(methodName);

        // Implement the interface function by reflectionClass<? > aClass = Class.forName(className); Method show = aClass.getDeclaredMethod("show");
        // Execute the corresponding methodObject o = aClass.newInstance(); show.invoke(o); }}Copy the code

Let’s do that. Okay, we’re done!

Custom annotations are commonly used in interceptors or AOP to design your own framework and make your code look elegant. It will then be used in conjunction with reflection, so if you’re not familiar with reflection, check out The Java Core Foundation of Reflection. Finally, the original is not easy, if you think it is good, please click a like!