Welcome to Java Annotations and Best Practices for Java Learning

directory

  • Introduction to Java Annotations

    • Annotations as labels
  • Overview of Java Annotations

    • What are annotations?

    • The usefulness of annotations

    • Principle of annotation

    • Yuan notes

    • Annotations in the JDK

  • Annotation processor combat

  • Different types of annotations

    • Class notes

    • Methods annotations

    • Parameter annotation

    • Variable annotations

  • Java annotation related interview questions

    • What are annotations? What are their typical use cases?

    • Describes some useful annotations in the standard library.

    • What object types can be returned from annotation method declarations?

    • Which program elements can be annotated?

    • Is there a way to limit the elements to which annotations can be applied?

    • What is a meta-annotation?

    • Will the following code compile?

  • Refer to the article


Introduction to Java Annotations

Annotation is a very important topic in Java, but it is often a bit difficult for beginners to understand.

In my opinion, one of the main characteristics of bad technical documentation is the use of technical terms to introduce technical terms. Such as:

Java annotations are used to provide metadata to Java code. As metadata, annotations don’t directly affect your code execution, but there are some types of annotations that can actually be used for this purpose. Java annotations were added to Java starting with Java5. These are Java annotations on most websites, and the explanation is true, but to be honest, when I first learned it, my mind went blank. What the hell is that? I heard it like I didn’t. Because the concept is too abstract, so beginners are really more difficult to understand, and then with their own development process constantly strengthen the practice, will slowly form a correct understanding of it.

As I write this, I am thinking. How can YOU make yourself or your readers more intuitive about the concept of annotations? Do you want to translate instructions on official documents? I immediately rejected the answer.

Later, I thought of something ———— ink, ink can be volatile, can be different colors, used to explain the annotations just right.

But as I continued to think, I came up with a better substitute for ink: a seal. The seal can be stained with different inks or prints, the words or patterns of the seal can be customized, and it can be poked on any surface you wish.

However, as I continued my thinking, I came up with a better alternative to a seal: a tag. A label is a convenience paper, and the contents of the label can be defined freely. Common ones are commodity price tags on shelves, book code labels in libraries, names and categories of chemical materials in laboratories, and so on.

And, to put it abstractly, a label is not necessarily a piece of paper, it can be an attribute evaluation of people and things. In other words, labels have an interpretation of abstract things.

So, with that in mind, I completed my knowledge upgrade, and I decided to annotate with labels.

Annotations as labels

Before, some news client comments had the habit of building a building, so “Jobs redefined the mobile phone, Luo Yonghao redefined the silly X” often very neatly appeared in the comment floor, and the majority of netizens in a quite long period of time for this kind of behavior never tired. This is the equivalent of labeling. In the eyes of some netizens, Luo yonghao has become a synonym for silly X.

The broad masses of netizens to Mr Luo to stick a label called “silly x”, they don’t really know Mr Luo, don’t know him as a teacher, hit the feat of refrigerator, blogging, but because of “dumb” tag, which would help them directly to Mr Luo this man quickly make evaluation, and then based on this, Mr Luo can become in dinner conversation, That’s the power of labels.

On the other side of the network, Luo relies on his personality charm to naturally gain a large number of loyal fans, they stick to luo is another label.

Lao Luo is still Lao Luo, but because people attach different labels to it, so it causes different views on him. People who don’t like him criticize and mock on the network all day long, while those who admire him will be willing to earn money to buy the release tickets of Smartisan mobile phone.

I don’t want to evaluate either behavior, but let me give you another example.

“Science says” is very popular on the Internet debate in recent years, the debater Ming Chen was another debater wei-wei ma attack say – “stand in the center of the universe called love”, and then a big label – – “the man with the chicken soup”, since then, the audience to see Ming Chen, the first thing in my mind is “chicken soup” three characters, In fact, Chen Ming is very good as a teacher, decent style, decent manners, but in the network, because of the environment of entertainment first, people are more willing to take the attitude of entertainment to recognize everything, so “chicken soup man” as Chen Ming himself said has become an inseparable label.

We can generalize abstractly, label is the evaluation and explanation of certain Angle of the behavior of things.

Here, finally can lead to the main notes of this article.

A beginner can think of annotations this way: think of code as living. A annotation is a label attached to some living individual in the code. In a nutshell, a annotation is like a label.

Before you start learning the syntax of any annotations, you can think of a annotation as a label. This will help you quickly understand what it does in general. If the beginner has a blank in the learning process, please don’t panic, say to yourself:

Annotations, labels. Annotations, labels.

Overview of Java Annotations

What are annotations?

That’s a question that many first-time developers have, right? Annontation is a new feature introduced in Java5, called annotations in Chinese. It provides a secure annotation-like mechanism for associating any information or metadata with program elements (classes, methods, member variables, and so on). Add more intuitive and explicit descriptions of application elements (classes, methods, member variables) that are independent of the application’s business logic and are used by the specified tool or framework. Annontation is used like a modifier in declarations of packages, types, constructors, methods, member variables, parameters, and local variables.

Java annotations are meta-information attached to code that is parsed and used by tools during compilation, runtime, and configuration. Annotations do not and cannot affect the actual logic of the code, but only serve as an aid. Included in the java.lang.annotation package.

The usefulness of annotations

1. Generate documentation. This is the most common and the earliest annotation provided in Java. 2. Track code dependencies to achieve the function of replacing configuration files. For example, Dagger 2 dependency injection, which will be very useful for future Java development with a lot of annotation configuration; 3. Format checking at compile time. If @Override comes before a method, it will be checked at compile time if your method does not override a superclass method.

Principle of annotation

Annotations are essentially a special interface that inherits annotations, implemented by dynamic proxy classes generated by the Java runtime. When we get annotations through reflection, we return $Proxy1, the dynamic proxy object generated by the Java runtime. Through a proxy object call custom annotations (interface) method, will eventually call AnnotationInvocationHandler invoke method. This method indexes the corresponding value from the Map memberValues. The source of memberValues is the Java constant pool.

Yuan notes

Java.lang. Annotation provides four meta-annotations that are used specifically to annotate other annotations (you need to use meta-annotations when customizing annotations) : @documented — Whether an annotation will be included in JavaDoc @Retention — when the annotation is used @target — Where the annotation is used @Inherited — Whether a child class is allowed to inherit the annotation

1.) @Retention — Defines the lifetime of the annotation

● retentionPolicy. SOURCE: discarded at compile time. These annotations are no longer meaningful after compilation, so they are not written to bytecode. @Override and @SuppressWarnings fall into this category. ● RetentionPolicy.CLASS: Discarded when the CLASS is loaded. Useful in the processing of bytecode files. ● RetentionPolicy.runtime: The annotation is never discarded and is retained at RUNTIME so that it can be read using reflection. Our custom annotations usually use this approach.Copy the code

2.) Target – Indicates where the annotation is used. The default value is any element, indicating where the annotation is used. The ElementType parameters available include

● ElementType.FIELD: member variables, objects, attributes (includingenumInstance) lowElementType.LOCAL_VARIABLE: Used to describe local variables ●ElementType.METHOD: Used to describe the method ●ElementType.PACKAGE: Used to describe packages ●ElementType.PARAMETER: Describes parameters ●ElementType.TYPE: Describes a class, interface (including annotation types), orenumThe statementCopy the code

3.) @documented — A simple Notation indicating whether annotation information is added to a Java document.

@Inherited – Defines the relationship between the annotation and the child class. @Inherited is a markup annotation, which explains that an annotated type is Inherited. If an annotation type with the @Inherited annotation is applied to a class, the annotation will be applied to a subclass of that class.

Annotations in the JDK

Let’s start with a few Java built-in annotations to warm you up.

@ Override demo

class Parent {
    public void run(a) {}}class Son extends Parent {
    /** * this annotation is to check if this method really overwrites the parent class * so we don't have to visually see if it overwrites the parent class */
    @Override
    public void run(a) {}}Copy the code

Deprecated demo class Parent {

/** * This annotation means that it is obsolete, but if it can be called, it can also be used normally. However, this method may be phased out in future version updates
@Deprecated
public void run(a) {}}public class JDKAnnotationDemo {
    public static void main(String[] args) {
        Parent parent = new Parent();
        parent.run(); // This method displays an outdated flag in the compiler}}Copy the code

@SuppressWarnings Demo class Parent {

// This annotation can be used to mask the warning generated by the compiler because the name defined is not used
// Any compile-time warnings that you don't want to see can be masked with this annotation, but it is not recommended
@SuppressWarnings("all")
private String name;
}
Copy the code

@ FunctionalInterface demo / * *

  • This annotation is a functional interface proposed by Java8 in which only one abstract method is allowed

  • */ @functionalInterface interface Func {void run(); }

Annotation processor combat

Annotation handler The annotation handler is the most important step in the process of using annotations. All annotations that appear in the code, and what they do, are defined in the annotation handler. Concept: Annotations themselves do not affect how the program is compiled, but the annotation processor does. Annotation processors can achieve additional functionality by using reflection at run time to retrieve annotation information used in program code. The premise is that our custom annotations use the retentionPolicy.runtime modifier. This is something we use a lot in development.

Let’s start by looking at how to use reflection at run time to get information about annotations used in an application. The following class annotations and method annotations.

Class aClass = apicontroller.class; Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations) {
    if(annotation instanceof ApiAuthAnnotation) {
        ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation;
        System.out.println("name: " + apiAuthAnnotation.name());
        System.out.println("age: "+ apiAuthAnnotation.age()); }} Method Method =...// Get the method object by reflection
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations) {
    if(annotation instanceof ApiAuthAnnotation) {
        ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation;
        System.out.println("name: " + apiAuthAnnotation.name());
        System.out.println("age: "+ apiAuthAnnotation.age()); }}Copy the code

For this section, see: Retrieving annotation information through Reflection

Next, I’ll demonstrate the annotation processor in real life using a practical adaptation in a company. Requirements: The backend interface of the site must be accessed only by those over 18 years of age, otherwise it cannot be accessed. Preparation: Define annotations (full annotations are used here), Use annotations (examples of annotations are used here) Next things to do: Write a slice that intercepts browser access to the annotated interface, retrieving the annotated information, and judging the age to determine whether access can continue.

Define the AOP aspects in the dispatcher-servlet.xml file

<aop:config> <! < AOP :pointcut id="apiAuthAnnotation" expression="@annotation(cn.caijiajia.devops.aspect.ApiAuthAnnotation)"/ > <! Aop :aspect ref= aop:aspect ref= aop:aspect ref="apiAuthAspect">
        <aop:around method="auth" pointcut-ref="apiAuthAnnotation"/>
    </aop:aspect>
</aop:config>
Copy the code

The section class processing logic is the annotation processor code such as

@Component("apiAuthAspect")
public class ApiAuthAspect {

    public Object auth(ProceedingJoinPoint pjp) throws Throwable {
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        ApiAuthAnnotation apiAuthAnnotation = method.getAnnotation(ApiAuthAnnotation.class);
        Integer age = apiAuthAnnotation.age();
        if (age > 18) {
            return pjp.proceed();
        } else {
            throw new RuntimeException("You're under 18, no access."); }}}Copy the code

Different types of annotations

Class notes

You can access class, method, or variable annotation information at runtime. Here is an example of accessing class annotations:

 Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: "+ myAnnotation.value()); }}Copy the code

You can also specify access to a class’s annotations as follows:

Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
Copy the code

Methods annotations

Here is an example of a method annotation:

public class TheClass {
  @MyAnnotation(name="someName", value = "Hello World")
  public void doSomething(a){}}Copy the code

You can access method annotations like this:

Method method = ... // Get the method object
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: "+ myAnnotation.value()); }}Copy the code

You can access the specified method annotation like this:

Method method = ... // Get the method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
Copy the code

Parameter annotation

Method parameters can also be annotated as follows:

public class TheClass {
  public static void doSomethingElse(
        @MyAnnotation(name="aName", value="aValue") String parameter){}}Copy the code

You can access Method parameter annotations via the Method object:

Method method = ... // Get the method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();

int i=0;
for(Annotation[] annotations : parameterAnnotations){
  Class parameterType = parameterTypes[i++];

  for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("param: " + parameterType.getName());
        System.out.println("name : " + myAnnotation.name());
        System.out.println("value: "+ myAnnotation.value()); }}}Copy the code

It is important to note Method. GetParameterAnnotations () Method returns an annotation type of two-dimensional arrays, each Method of parameter contains an array of annotation.

Variable annotations

Here is an example of a variable annotation:

public class TheClass {

  @MyAnnotation(name="someName", value = "Hello World")
  public String myField = null;
}
Copy the code

You can access a variable’s annotation like this:

Field field = ... 
<pre>Annotation[] annotations = field.getDeclaredAnnotations();

for(Annotation annotation : annotations){
 if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("name: " + myAnnotation.name());
 System.out.println("value: "+ myAnnotation.value()); }}Copy the code

You can access the specified variable annotations like this:

Field field = ...
<pre>
Annotation annotation = field.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
 MyAnnotation myAnnotation = (MyAnnotation) annotation;
 System.out.println("name: " + myAnnotation.name());
 System.out.println("value: " + myAnnotation.value());
}
Copy the code

Java annotation related interview questions

What are annotations? What are their typical use cases?

Annotations are metadata bound to elements of a program’s source code and have no effect on the operation of running code.

Their typical use case is:

  • Compiler information – With annotations, the compiler can detect errors or suppress warnings

  • Compile-time and deploy-time processing – Software tools can handle annotations and generate code, configuration files, etc.

  • Runtime processing – Annotations can be examined at run time to customize the behavior of the program

Describes some useful annotations in the standard library.

There are several annotations in the java.lang and java.lang.annotation packages, the more common ones include but are not limited to:

  • @override – Marks whether the method overrides an element declared in a superclass. If it fails to override the method properly, the compiler issues an error

  • @deprecated – Indicates that the element is Deprecated and should not be used. If a program uses a method, class, or field marked with this annotation, the compiler will issue a warning

  • @SuppressWarnings – Tells the compiler to disallow specific warnings. Most commonly used when interface with legacy code written before generics

  • @functionalinterface – introduced in Java 8, indicating that a type declaration is a FunctionalInterface whose implementation can be provided using Lambda Expression

What object types can be returned from annotation method declarations?

The return type must be one of the basic types, String, Class, Enum, or array. Otherwise, the compiler throws an error.

Here is an example code that successfully follows this principle:

enum Complexity {
    LOW, HIGH
}

public @interface ComplexAnnotation {
    Class<? extends Object> value();

    int[] types();

    Complexity complexity(a);
}
Copy the code

The next example will not compile because Object is not a valid return type:

public @interface FailingAnnotation {
    Object complexity();
}
Copy the code

Which program elements can be annotated?

Annotations can be applied to multiple places throughout the source code. They can be applied to class, constructor, and field declarations:

@SimpleAnnotation
public class Apply {
    @SimpleAnnotation
    private String aField;

    @SimpleAnnotation
    public Apply(a) {
        // ...}}Copy the code

Methods and parameters:

@SimpleAnnotation
public void aMethod(@SimpleAnnotation String param) {
    // ...
}
Copy the code

Local variables, including loop and resource variables:

@SimpleAnnotation
int i = 10;

for (@SimpleAnnotation int j = 0; j < i; j++) {
    // ...
}

try (@SimpleAnnotation FileWriter writer = getWriter()) {
    // ...
} catch (Exception ex) {
    // ...
}
Copy the code

Other annotation types:

@SimpleAnnotation
public @interface ComplexAnnotation {
    // ...
}
Copy the code

Even packages, via package-info.java files:

@PackageAnnotation
package com.baeldung.interview.annotations;
Copy the code

Starting with Java 8, they can also be applied to the use of types. To do this, the annotation must specify an @target annotation with a value of elementType.use:

@Target(ElementType.TYPE_USE)
public @interface SimpleAnnotation {
    // ...
}
Copy the code

Annotations can now be applied to class instance creation:

new @SimpleAnnotation Apply();
Copy the code

Type conversion:

aString = (@SimpleAnnotation String) something;
Copy the code

In the interface:

public class SimpleList<T>
  implements @SimpleAnnotation ListThe < @SimpleAnnotation T> {
    // ...
}
Copy the code

Throw an exception on:

void aMethod(a) throws @SimpleAnnotation Exception {
    // ...
}
Copy the code

Is there a way to limit the elements to which annotations can be applied?

Yes, the @target annotation can be used for this purpose. If we try to use annotations in a context that is not applicable, the compiler will issue an error.

Here is an example that restricts the use of the @SimpleAnnotation annotation only to field declarations:

@Target(ElementType.FIELD)
public @interface SimpleAnnotation {
    // ...
}
Copy the code

If we want it to work in more contexts, we can pass multiple constants:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })
Copy the code

We can even make an annotation, so it can’t be used to annotate anything. This may come in handy when the declared type is used only as a member type in a complex annotation:

@Target({})
public @interface NoTargetAnnotation {
    // ...
}
Copy the code

What is a meta-annotation?

Meta-annotations annotations that apply to other annotations.

All annotations that don’t use the @target tag or are tagged with it but contain the ANNOTATION_TYPE constant are meta-annotations:

@Target(ElementType.ANNOTATION_TYPE)
public @interface SimpleAnnotation {
    // ...
}
Copy the code

Will the following code compile?

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })
public @interface TestAnnotation {
    int[] value() default {};
}
Copy the code

Can’t. If the same enumeration constant appears multiple times in the @target annotation, this is a compile-time error.

Removing duplicate constants will make the code compile successfully:

@Target({ ElementType.FIELD, ElementType.TYPE})
Copy the code

Refer to the article

Blog.fundodoo.com/2018/04/19/… Blog.csdn.net/qq\_3793925… Blog.51cto.com/4247649/210… www.jianshu.com/p/2f2460e6f… Blog.csdn.net/yuzongtao/a…