A detailed explanation of the basic concepts based on Java annotations of annotations

  • 2020-04-01 01:44:00
  • OfStack

What is an Annotation:

Annotations are the ways and methods that Java provides for elements in a metaclass to associate any information with any metadata. An Annotion is an interface through which a program can get the specified program element's Annotion object by reflection, and then get the metadata inside the annotation by Annotion object.

Annotations were introduced in JDK5.0 and later. It can be used to create documents, track dependencies in code, and even perform basic compile-time checks. In some ways, annotations are used like modifiers and are applied to declarations of packages, class types, constructors, methods, member variables, parameters, and local variables. This information is stored in the "name=value" structure pair of the Annotation.

The members of an Annotation are declared as parameterless methods in the Annotation type. Its method name and return value define the name and type of the member. There is a specific default syntax here that allows you to declare the default value of any Annotation member: an Annotation can have a name=value pair as the value of an Annotation member that has no default value defined, or it can use a name=value pair to override the default value of other members. This is somewhat analogous to class inheritance, where the constructor of the parent class can be used as the default constructor of the subclass, but can also be overridden by the subclass.

Annotations can be used to associate any information for a program element (class, method, member variable, etc.). It is important to note that there is a basic rule here: an Annotation cannot affect the execution of the program code, and the code always executes regardless of whether the Annotation is added or removed. In addition, although some annotations are accessed at run time through Java's reflection API methods, the Java language interpreter ignores these annotations as it works. It is because the Java virtual machine ignores annotations that the Annotation type "doesn't work" in the code. The information in the annotation type can only be accessed and processed by a companion tool. We'll cover the standard Annotation and meta-annotation types in this article, and the tool that accompanies these Annotation types is the Java compiler (which handles them in a special way, of course).

--------------------------------------------------------------------------------

What is metadata (metadata) :

Metadata is derived from the word metadata, which means "data about data."
Metadata has many functions, for example, you may have used Javadoc's comments to automatically generate documentation. This is one of the metadata capabilities. In general, metadata can be used to create documents, track code dependencies, perform compile-time format checks, and replace existing configuration files. If we want to classify the role of metadata, there is no clear definition, but we can roughly divide it into three categories according to the role it plays:
1. Document: generate documents from metadata identified in the code
2. Code analysis: code is analyzed using metadata identified in the code
Compile checking: enables the compiler to perform basic compile checking with metadata identified in the code
In Java, metadata exists in Java code in the form of tags. The existence of metadata tags does not affect the compilation and execution of program code, it is just used to generate other files or descriptions of code that is known to be run at runtime.
In summary:
First, metadata exists in Java code in the form of tags.
Second, metadata describes information that is type-safe, meaning that the fields inside the metadata are of a specific type.
Third, metadata requires additional processing by tools other than the compiler to generate other parts of the program.
Fourth, metadata can exist only at the Java source level, or within a compiled Class file.

--------------------------------------------------------------------------------

  Annotation and Annotation type:

Annotation:

Annotations use the new syntax introduced in java5.0, which behaves much like modifiers such as public and final. Each Annotation has a name and number of members > = 0. Each Annotation member has a name and value called the name=value pair (just like a javabean), and the name=value carries the Annotation's information.

The Annotation type:

The Annotation type defines the name, type, and member default value of the Annotation. An Annotation type can be described as a special Java interface whose member variables are restricted, and the new syntax is required to declare the Annotation type. When we access an Annotation through the Java reflection API, the return value will be an object that implements the Annotation type interface, and by accessing that object we can easily access its Annotation members. A later section will mention the three standard Annotation types that are included in the java.lang package for Java 5.0.

--------------------------------------------------------------------------------

Classification of annotations:

According to the number of annotation parameters, we can divide annotations into three categories:
1. Tag annotations: an Annotation type without a member definition is called a tag Annotation. This Annotation type just USES its presence or absence to give us information. For example, the following system annotation @override;
2. Single value annotations
3. Full notes

According to the Annotation usage method and purpose, we can divide Annotation into three categories:
1. System annotations built into JDK
2. RMB notes
3. Custom annotations

--------------------------------------------------------------------------------

  Built-in standard notes:

The syntax of annotations is relatively simple, except for the use of @ symbol, it is basically consistent with the inherent syntax of Java. There are three standard annotations built into JavaSE, defined in java.lang:
Override: modifies the method that overrides the parent class;
Deprecated: pertaining to an out-of-date method;
SuppressWarnnings: notifies the Java compiler to disable a specific build warning.

Let's take a look at three scenarios in which built-in standard annotations are used and used.

--------------------------------------------------------------------------------

  Override, qualifies overrides of superclass methods:

Override is a tag annotation type that is used as an annotation method. It shows that the annotated method overrides the parent method, acting as an assertion. If we use this Annotation in a method that does not override a parent method, the Java compiler will alert us with a compilation error. This annotaton often comes into play when we try to override a parent method and actually write the wrong method name. Using methods is extremely simple: when using this annotation, you simply prefix the modified method with @override. The following code is an instance of a displayName() method that attempts to Override the parent class with @override, with a misspelling:


public class Fruit {
    public void displayName(){
        System.out.println(" The name of the fruit is: *****");
    }
}
class Orange extends Fruit {
    @Override
    public void displayName(){
        System.out.println(" The name of the fruit is orange ");
    }
}
class Apple extends Fruit {
    @Override
    public void displayname(){
        System.out.println(" The name of the fruit is: apple ");
    }
}

The Orange class compiles without any problems, and the Apple class prompts for errors when it compiles. The @override annotation can only be used for methods, not for other program elements.
--------------------------------------------------------------------------------

@deprecated, tag is out of date:

The same Deprecated is also a tag annotation. When a type or type member is decorated with @deprecated, the compiler discourages the use of the annotated program element. And this modification has a certain degree of "continuity" : if we use this obsolete type or member in our code by inheritance or overwriting, the compiler still alarms us if the inherited or overridden type or member is not declared as @deprecated.

It's worth noting that the annotation type @deprecated differs from the @deprecated tag in javadoc: the former is recognized by the Java compiler, while the latter is recognized by the javadoc tool to generate a document (containing a description of why the program member has passed, and how it should be disabled or substituted).

In Java 5.0, the Java compiler still looks for the @deprecated javadoc tag as it did in previous versions and USES them to generate warning messages. However, this will change in a later release, and we should start using @deprecated to modify outdated methods now instead of @deprecated javadoc tag.

In the following program, the @deprecated annotation is used to mark the expiration of the method, and the @deprecated tag is used to mark the method's expiration in the method annotation. The code is as follows:


class AppleService {
    public void displayName(){
        System.out.println(" The name of the fruit is: apple ");
    }

    
    @Deprecated
    public void showTaste(){
        System.out.println(" The apple taste of fruit is: crisp and sweet ");
    }

    public void showTaste(int typeId){
        if(typeId==1){
            System.out.println(" The taste of fruit apple is: acerbity ");
        }
        else if(typeId==2){
            System.out.println(" The taste of fruit apple is: soft and sweet ");
        }
        else{
            System.out.println(" The apple taste of fruit is: crisp and sweet ");
        }
    }
}
public class FruitRun {
    
    public static void main(String[] args) {
        Apple apple=new Apple();
        apple.displayName();    

        AppleService appleService=new AppleService();
        appleService.showTaste();
        appleService.showTaste(0);
        appleService.showTaste(2);
    }
}

The showTaste() method of the AppleService class is labeled as obsolete by @deprecated, and when used in the FruitRun class, the compiler gives a hint that the method has expired and is not recommended.

--------------------------------------------------------------------------------

SuppressWarnnings, suppress compiler warning:

@suppresswarnings is used to selectively close compiler warnings on classes, methods, member variables, and variable initializations. In java5.0, the sun-supplied javac compiler provides us with the -xlint option to warn the compiler of legitimate program code, which in a way represents a program error. For example, when we use a generic collection class without providing its type, the compiler prompts an "unchecked warning" warning. Usually when this happens, we need to look for the code that causes the warning. If it does represent an error, we need to correct it. For example, if the warning message indicates that the switch statement in our code does not cover all possible cases, we should add a default case to avoid this warning.
Sometimes we can't avoid this warning; for example, we can't avoid this unchecked warning when we use generic collection classes that have to interact with non-generic older code. At this point the @suppresswarning comes in handy, and the @suppresswarnings modifier is added before the method to tell the compiler to stop warning the method.
SuppressWarning is not a token annotation. It has a member of type String[] whose value is the forbidden warning name. For the javac compiler, the warning name that is valid by the -xlint option is also valid for @suppresswarings, and the compiler ignores the unrecognized warning name.
The annotation syntax allows the annotation name to be followed by a parenthesis with a comma-separated name=value to assign to the member used for the annotation. Examples are as follows:


public class FruitService {

    @SuppressWarnings(value={ "rawtypes", "unchecked" })
    public static  List<Fruit> getFruitList(){
        List<Fruit> fruitList=new ArrayList();
        return fruitList;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static  List<Fruit> getFruit(){
        List<Fruit> fruitList=new ArrayList();
        return fruitList;
    }
    @SuppressWarnings("unused")
    public static void main(String[] args){
        List<String> strList=new ArrayList<String>();
    }
}

In this example, the SuppressWarnings annotation type only defines a single member, so there is only a simple value={... } as the name=value pair. Because the member value is an array, braces are used to declare the array value. Note: we can abbreviate annotation in the following case: when an annotation has only a single member and the member is named "value=". You can leave out "value=". For example, the suppressalert annotation on getFruit() above is abbreviated.

  A brief description of the usual parameter values for the SuppressWarnings annotation:

1. Deprecation: warning when a class or method is disapproved of;
2. Unchecked: warnings when unchecked conversions are performed, such as using collections without Generics to specify the type of collection to hold;
3. Fallthrough: warning when the Switch block goes directly to the next situation without a Break;
4. Path: warning when there is a path that does not exist in the classpath, source file path, etc.
5. Serial: warning when the serialVersionUID definition is missing on a serializable class;
6. Finally: a warning when any finally clause cannot be completed properly;
7. All: a warning about all of the above.


Related articles: