Today’s sharing started, please give us more advice ~

This article will examine Java annotations in several ways:

  1. Annotations are tags, and annotations are used to explain code
  2. Basic syntax for annotations @interface
  3. Meta-annotations of annotations
  4. Attributes of annotations
  5. Annotations are intended for compiler and tool-type software
  6. Annotations are extracted using Java’s reflection technology, which is slow, so you need to be careful about the time cost of using annotations

A brief introduction to annotations

Java annotations are used to provide metadata to Java code.

Metadata is the data used to describe data, or, more generally, the relationships between code, or the internal relationships between code and other resources, such as database tables. In some technical frameworks, such as Struts and Hibernate, metadata is unconsciously used. For Struts, metadata refers to struts-config.xml; For Hibernate, this is an HBM file. The metadata described above is based on XML files or other forms of separate configuration files. This is an indication of some inconvenience.

1. Separation from described files is not conducive to consistency maintenance;

2. All such files are ASCII files with no explicit type support. Based on the widespread use of metadata, JDK5.0 introduces the concept of annotations to describe metadata. In Java, metadata exists in Java code in the form of tags. The presence of metadata tags does not affect the compilation and execution of program code. In short, annotations are what labels mean.

How to create annotations

When JDK5.0 came out, there were four types in the Java language: class, enum, interface, annotation @interface, all at the same level. Java uses annotations to represent metadata.

package com.guor.ClientNew; Public @interface MyAnnotation {// Define public final static property int age = 25; // Define the public abstract method String name(); }Copy the code

Java annotations are essentially interfaces, interfaces that inherit the Annotation interface.

Meta notes

A meta-comment is a comment that can be added to a comment, or a basic comment that can be applied to other comments.

Meta labels include @Retention, @documented, @target, @Inherited, and @REPEATable.

1. @ Retention

Retention is Retention

When @Retention is applied to annotations, it explains the annotation’s life cycle.

The retentionPolicy.source annotation is only retained at the SOURCE stage and is discarded and ignored when the compiler compiles.

The retentionPolicy.class annotation is only retained until compilation and is not loaded into the JVM.

The retentionPolicy.runtime annotation can be retained until the program is run and loaded into the JVM.

2, @ Documented

As the name implies, this meta-annotation must be related to the document. It provides the ability to include elements from annotations into Javadoc.

3, @ Target

Indicate where the notes are used.

  • Elementtype. ANNOTATION_TYPE Annotates an annotation
  • Elementtype. CONSTRUCTOR can be annotated to a CONSTRUCTOR
  • Elementtype. FIELD can be used to annotate attributes
  • Elementtype. LOCAL_VARIABLE can be used to annotate local variables
  • ElementType.METHOD can annotate methods
  • Elementtype. PACKAGE can annotate a PACKAGE
  • Elementtype. PARAMETER can be used to annotate parameters within a method
  • Elementtype. TYPE can annotate a TYPE, such as a class, interface, or enumeration

4, @ Inherited

Lnherited means inherited.

If a superclass is annotated with @Inherited annotations, then the child class inherits the superclass’s annotations if it is not applied to any of the annotations.

The code examples

5, @ the Repeatable

Repeatable means Repeatable. Repeatable @repeatable was added to Java 1.8, so it’s a new feature.

What annotations are used more than once? Usually the value of an annotation can be multiple at the same time.

In life, a person often has many identities. How can I use each identity as a note?

Declare a Persons class to hold all identities

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {
Person[] value();
}
Copy the code

Elementtype. Type indicates that a Type, such as a class, interface, or enumeration, can be annotated.

@Retention is the Retention time of annotations, and retentionPolicy. RUNTIME is when the program runs.

The Person comments:

@Repeatable(Persons.class)
public @interface Person{
String role() default "";
}
Copy the code

The @Repeatable parentheses are equivalent to the container used to hold the annotation content.

Declare a Man class and give it some identity.

@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man {
String name="";
}
Copy the code

Access this annotation in the main method:

public static void main(String[] args) { Annotation[] annotations = Man.class.getAnnotations(); System.out.println(annotations.length); Persons p1=(Persons) annotations[0]; for(Person t:p1.value()){ System.out.println(t.role()); }}Copy the code

The following code results in the same output, but can first determine whether the corresponding annotation, more rigorous.

if(Man.class.isAnnotationPresent(Persons.class)) { Persons p2=Man.class.getAnnotation(Persons.class); for(Person t:p2.value()){ System.out.println(t.role()); }}Copy the code

Running results:

Attributes of annotations

Annotation properties are also called member variables, and annotations have only member variables, not methods. An annotation’s member variable is declared in the annotation’s definition as a “method with no arguments,” whose method name defines the name of the member variable, and whose return value defines the type of the member variable.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id();
String msg();
}
Copy the code

The TestAnnotation annotation is defined in the code above. The annotation has two attributes: ID and MSG. When used, we should assign values to them.

This is done by enclosing the annotation in parentheses with the form value= “”, separated from multiple attributes by a comma.

@TestAnnotation(id=3,msg="hello annotation")
public class Test {
}
Copy the code

Note that the type of an attribute defined in an annotation must be the eight basic data types plus classes, interfaces, annotations, and their arrays.

Attributes in annotations can have default values, which need to be specified with the default key value. Such as:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { public int id() default - 1; Public String MSG () default "MSG "; }Copy the code

The default value of the ID attribute in the TestAnnotation notation is -1 and the default value of the MSG attribute is jitter.

It can be applied like this.

@TestAnnotation()
public class Test {}
Copy the code

Because of the default, the assignment in the parentheses following the @testannotation notation is no longer needed; this step can be omitted.

And there’s another situation. If an annotation contains only one attribute named value, you can apply the annotation directly to the attribute value in parentheses.

public @interface Check {
String value();
}
Copy the code

In the code above, the Check annotation only has the value attribute. So you can apply it this way.

@Check(“hi”)

int a;

This has the same effect as the following

@Check(value=”hi”)

int a;

Finally, note that an annotation has no attributes. Such as

public @interface Perform {}

So when applying this annotation, the parentheses can be omitted.

@Perform

public void testMethod(){}

5. Java preset annotations

With this knowledge, we can now define our own annotations. The Java language itself already provides several annotations.

1. @ Override

This should be familiar, reminding subclasses to Override the @override method in their parent class

2, @ Deprecated

This annotation means that the method or class is no longer recommended. The deletion line appears when the call is made, but it does not mean that it cannot be used. It simply means that it is not recommended because there are better methods to call.

So don’t you just delete it?

Because in a project, the project is large, the code is more, and in the subsequent development process, some methods may not very reasonable, this time to write a method, and previous method can’t delete, because may call it elsewhere, so use this annotation, OK!

3, @ SuppressWarnings

Prevent warning meaning.

The effect of this annotation is to give the compiler an instruction to be silent about certain warnings within the annotated code element.

Note: this note has a lot of parameters, here is not to repeat, if necessary, please baidu!

4, @ SafeVarargs

Parameter safety type annotations.

Its purpose is to warn developers not to do anything unsafe with arguments, and its existence prevents compilers from generating such warnings.

The Java compiler will emit an unchecked warning when declaring constructors or methods that have mutable arguments of obscure types, such as generics. Given this situation, if your program determines that the declared constructor and method body is no problem, you can use the @safevarargs markup so that the Java compiler will not emit unchecked warnings!

Take a look at the @Safevarargs declaration in Java SE:

package java.lang;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}
Copy the code

As we know from the Java source code declaration, the @Safevarargs annotation can only be used to mark constructors and methods. Since the retention policy declaration is RUNTIME, this annotation can be used at RUNTIME.

The @safevarargs annotation can only be used for static or final methods.

Example code:

Methods for generic parameters, without comments:

package com.guor.ClientNew; public class SafeVarargsAnnotation<S> { private S[] args; public SafeVarargsAnnotation(S... args){ this.args = args; } public void loopPrintArgs(S... args){ for (S arg : args){ System.out.println(arg); } } public final void printSelfArgs(S... args){ for (S arg : this.args) { System.out.println(arg); } } public static <T> void loopPrintInfo(T... infos){ for(T info:infos){ System.out.println(info); } } public static void main(String[] args) { SafeVarargsAnnotation.loopPrintInfo("A","B","C"); }}Copy the code

Proper use of annotations:

package com.guor.ClientNew; public class SafeVarargsAnnotation<S> { private S[] args; // Constructor can use @safevarargs @safevarargs public SafeVarargsAnnotation(S... args){ this.args = args; } // You cannot use @safevarargs here, because this method is not declared static or final. You can use the @SuppressWarnings(" Unchecked ") public void loopPrintArgs(S... args){ for (S arg : args){ System.out.println(arg); SafeVarargs public final void printSelfArgs(S... args){ for (S arg : this.args) { System.out.println(arg); @safevarargs public static <T> void loopPrintInfo(T... infos){ for(T info:infos){ System.out.println(info); } } public static void main(String[] args) { SafeVarargsAnnotation.loopPrintInfo("A","B","C"); }}Copy the code

5, @ FunctionalInterface

Java 8 introduces a new annotation for functional interfaces, @functionalinterface, which is used for compile-level error checking. With this annotation, the compiler will report an error when you write an interface that does not conform to the FunctionalInterface definition.

They are primarily used for Lambda expressions and method references (actually, you can also think of Lambda expressions).

A functional interface is defined as follows:

@FunctionalInterface
interface GreetingService
{
void sayMessage(String message);
}
Copy the code

Lambda expressions can then be used to represent an implementation of this interface (note: Prior to JAVA 8, it was typically implemented using anonymous classes) :

GreetingService greetService1 = message -> System.out.println(“Hello ” + message);

A brief introduction to lambda expressions

Notes and reflections

Annotations are obtained by reflection

You can first determine whether an annotation is applied to a Class object using the isAnnotationPresent() method.

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}

2. Method getAnnotations()

public Annotation[] getAnnotations() {}

The former method returns the annotations of the specified type, and the latter method returns all annotations annotated to the element.

3. Code examples:

① Without notes:

Nothing!

② Add a note

This is the default value for ID and MSG in TestAnnotation.

The above example only reviews annotations on a class, as well as annotations on properties and methods. Again, fake hands and reflexes.

③ Comments on attributes and methods:

package com.guor.Annotation; import OSChina.ClientNew.Hero; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; @TestAnnotation(msg="hello") public class Test { @Check(value="hi") int a; @Perform public void testMethod(){} @SuppressWarnings("deprecation") public void test1(){ Hero hero = new Hero(); hero.say(); hero.speak(); } public static void main(String[] args) { boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);  if ( hasAnnotation ) { TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class); Println ("id:"+testAnnotation. Id ()); // Get the class annotation system.out.println ("id:"+testAnnotation. System.out.println("msg:"+testAnnotation.msg()); } try { Field a = Test.class.getDeclaredField("a"); a.setAccessible(true); Check Check = a.getAnnotation(check.class); if ( check ! = null ) { System.out.println("check value:"+check.value()); } Method testMethod = Test.class.getDeclaredMethod("testMethod"); if ( testMethod ! = null) {/ / acquisition approach the annotations in the Annotation [] ans = testMethod. GetAnnotations (); for( int i = 0; i < ans.length; i++) { System.out.println("method testMethod annotation:"+ans[i].annotationType().getSimpleName()); } } } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(e.getMessage()); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(e.getMessage()); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(e.getMessage()); }}}Copy the code

Note that @Retention(retentionPolicy.runtime) is required if an annotation is to be successfully extracted at RUNTIME.

7. Usage scenarios of annotations

1. Official interpretation of notes

Annotations are a set of metadata that provides data to interpret program code, but annotations are not part of the interpreted code itself. Annotations have no direct effect on how the code works.

2. Annotations have many uses:

① Provide information to the compiler: The compiler can use annotations to detect errors or warnings

Compile time processing: Software tools can use annotation information to generate code, HTML documents, or other response processing.

③ Runtime processing: Some annotations can accept code extraction while the program is running.

It is important to note that annotations are not part of the code itself.

3. Annotations are used in too many places, such as JUnit testing framework, typical usage

@test marks the method to be tested with addition_isCorrect().

The SSM framework, for example, uses a lot of annotations.

Application examples of annotations

Retention indicates the Retention level of the annotation, Target indicates where the annotation can be annotated, and @Inherited indicates that the annotation is automatically Inherited.

The above program declares a Bird abstract class, and mark the Desc annotations, describe the birds color is white, and then write a Sparrow Sparrow class, it has two constructors, one is the default constructor, we often see a Sparrow is grayish, another constructor is the color of the custom the Sparrow, He then defined a nest (factory method model) that specializes in bird reproduction. His production method reproduced sparrows of different colors based on the reality-like annotation information. We write a client call as follows:

What does it print out? If the subclass Sparrow does not have any annotations, then the bd variable in the factory method will be null and the constructor should be called without arguments.

Why is the output white? This is the color we added to the parent class, why? And that’s because we have @desc annotation on the annotations, which means that when we add @desc to Bird, all of its children will inherit @desc from the parent.

Summary:

Java annotations, also called Java annotations, are an Annotation mechanism introduced in JDK5.0. You can annotate packages, classes, interfaces, fields, method parameters, local variables, and so on. Annotations can be set to exist in different life cycles, such as SOURCE (in the SOURCE code), CLASS (in the CLASS file, which is reserved by default), and RUNTIME (in the RUNTIME).

Today’s share has ended, please forgive and give advice!