当前位置:网站首页>Interviewer: what do you think of annotation

Interviewer: what do you think of annotation

2020-12-06 14:40:45 Tian Weichang

The main contents of this paper are as follows :

 

 

background

Now it is in the era of annotation , annotation @Override , This annotation can't be more familiar , also @Controller、@RequestMapping、@Service.....

Annotation is already a necessary skill in development .

If you're asked for notes during an interview , I can't say a word 123, I have to go back and wait for the notice .

What is annotation ?

annotation annotation yes JavaSE5.0 New features in . It can be understood that annotation is a kind of mark , This tag can be used in compiling 、 Class loading 、 Read at run time , And carry out the corresponding treatment .

It can be added to any element of the program : Package declaration 、 Type declaration 、 Construction method 、 Common method 、 Member variables 、 Parameters .

The boss of annotation :

package java.lang.annotation;
    // It's an interface 
    public interface Annotation {    
        boolean equals(Object obj);
        int hashCode(); 
        String toString(); 
        // Get annotation type 
        Class<? extends Annotation> annotationType();
    }

JDK The self provided meta annotation for us , Now let's talk about JDK Meta annotation of .

What are the meta notes ?

JDK Give us five meta annotations , be located java.lang.annotation Package directory . Respectively :

  • @Retention
  • @Target
  • @Documented
  • @Inherited
  • @Repeatable

Retention annotation

Literal translation :

 

 

The annotation is to define what stage the annotation is applied to .

compile 、 Class loading 、 function ( Most used )

Annotation source code :

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
        /**
         * Returns the retention policy.
         * @return the retention policy
         */
        RetentionPolicy value();
    }

Retention policy

package java.lang.annotation;
    public enum RetentionPolicy { 
        SOURCE, 
        CLASS, 
        RUNTIME
    }

SOURCE: Only in Java In the source code , The compiler just discards it when it compiles .

CLASS: The compiler records annotations in .class In file . When running Java The program ,JVM Cannot get annotation information . This is the default .

RUNTIME: The compiler records annotations in .class In file . When running Java The program ,JVM You can also get annotation information . The program can get annotation information through reflection .

Be careful : If you use this annotation, you must specify value Value .

Target annotation

Literal meaning is the goal , Let's look at the source code of the viewer :

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
        // Element type 
        ElementType[] value();
    }
    public enum ElementType { 
        TYPE, 
        FIELD, 
        METHOD, 
        PARAMETER, 
        CONSTRUCTOR, 
        LOCAL_VARIABLE, 
        ANNOTATION_TYPE, 
        PACKAGE, 
        /** @since 1.8*/
        TYPE_PARAMETER,
        /** @since 1.8*/
        TYPE_USE
    }

Target Annotation is when a declaration creates an annotation , Indicates which elements of the program the annotation can be applied to .

It also contains a name called value Member variables of ,value The values of member variables are as follows

  • ANNOTATION_TYPE: Specifies that the current annotation can only modify other annotations
  • CONSTRUCTOR: Specifies that the current annotation can only modify constructor methods
  • FIELD: Specifies that the current annotation can only modify member variables
  • LOCAL_VARIABLE: Specifies that the current annotation can only modify local variables
  • METHOD: Specifies that the current annotation can only modify methods
  • PACKAGE: Specifies that the current annotation can only decorate packages
  • PARAMETER: Specifies that the current annotation can only modify parameters
  • TYPE: Specifies that the current annotation can modify the class , Interface , Other notes , Enumeration, etc

for instance : frequently-used Spring Annotations @Controller, Is used to act on classes .

 

 

Documented annotation

The literal meaning is document .@Documented Used to describe other types of annotation Should be marked as a member of the program's public API, So it can be, for example javadoc This kind of reference text File .Documented It's a tag comment , There are no members .

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

It is mainly used to generate documents , Basically, it's rarely used at work , As an understanding .

Inherited annotation

Literally :

 

 

@Inherited Annotation is when a declaration creates an annotation , The inheritance will have the annotation .

Inherited Source code :

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Inherited {
    }

If a class uses the annotation @Xx, Then its subclass will be automatically annotated with this annotation @Xx Modified .

Use templates :

@Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Inherited
    public @interface A {
        
    }
    @A
    public class Base {
        
    }
    //Sub It also has @A
    public class Sub extends Base {
    }

Repeatable annotation

@Repeatable Yuan notes , seeing the name of a thing one thinks of its function , Repeat the note , It's when the declaration creates the annotation , Specifies that the annotation can be used more than once by the same program element . This is a JDK8 New comments , Repeating annotations is just a simplification , This simplification is an illusion . Multiple repeating annotations are actually used as “ Containers ” Annotated value Array elements of member variables .

For example, below Spring Notes in ComponentScan:

@Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Repeatable(ComponentScans.class)
    public @interface ComponentScan {
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    public @interface ComponentScans {
     ComponentScan[] value();
    }

Use cases

import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScans;
    
    @ComponentScans(value = {
            @ComponentScan(value = "com.tian.pakage0"),
            @ComponentScan(value = "com.tian.pakage1")})
    public class MainConfig {
        @Bean
        public User person() {
            return new User();
        }
    }

Basic notes

Annotations must be handled with tools , The tool is responsible for extracting metadata contained in annotations , The tool also adds additional functionality based on this metadata . Let's get to know 5 The use of basic annotations .

  • Override
  • SafeVarargs
  • SuppressWarnings
  • FunctionalInterface
  • Deprecated

Let's talk about these five notes .

Override

Used to identify methods , Identifies that the method belongs to a method that overrides the parent class .

// It can only be used in methods 
    @Target(ElementType.METHOD)
    // The source code will be compiled using 
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }

This annotation appears to be a method of overriding the parent class , It can only be used in methods , And for the compilation phase , When we were developing , If annotations are not used properly , When the source code is compiled, it will prompt immediately .

SafeVarargs

@SafeVarargs The note is in JDK7 Introduced in . This note applies to the acceptance of varargs Parametric final and static Method or constructor . This annotation is used to ensure that the method does not varargs Parameters perform unsafe operations . from Java9 Start ,@SafeVarargs Annotations also apply to private instance methods .

@SafeVarargs Source code

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
    public @interface SafeVarargs {}

Use cases

If you don't use this annotation

public class SafevarargsTest {
    public static void main(String[] args) {
        //  Passing variable parameters , Parameters are generic collections 
        display(10, 20, 30);
        //  Passing variable parameters , Parameters are non generic sets 
        display("10", 20, 1000L); //  There will be compilation warnings 
    }
    public static <T> void display(T... array) {
        for (T arg : array) {
            System.out.println(arg.getClass().getName() + ":" + arg);
        }
    }
}

display The method will prompt

 

 

If we add this annotation to this method

 

 

The code above is in variable parameters display Added before @SafeVarargs annotation , You can also use it @SuppressWarnings("unchecked") annotation , But , In comparison with the two @SafeVarargs Annotations are more suitable for .

Be careful :@SafeVarargs Notes do not apply to non static Or not final Declared method , For undeclared as static or final Methods , If , To suppress unchecked Warning , have access to @SuppressWarnings annotation .

SuppressWarnings

Used to selectively turn off compiler on class 、 Method 、 Member variables 、 Warning for variable initialization .

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface SuppressWarnings {
        String[] value();
    }

At compile time, you will be prompted , It is also widely used , It can be applied to classes 、 Interface 、 enumeration 、 Method 、 Field etc. .

What we have seen most in the development process should be when the data is stored in a collection , Take the following example .

 

 

But if we let go of the first line of code comments .

 

 

So there's no hint .

FunctionalInterface

JDK8 The new annotation .@FunctionalInterface Mark on the interface ,“ Functional interface ” An interface that contains only one abstract method .

Source code

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface FunctionalInterface {}

1、 The annotation can only be marked on ” There is and only one abstract method ” On the interface of .

2、JDK8 Static methods and default methods in the interface , They are not abstract methods .

3、 Interface default inheritance java.lang.Object, So if the interface display declaration overrides Object Medium method , So it's not an abstract method .

4、 This annotation is not necessary , If an interface conforms to ” Functional interface ” Definition , So it doesn't matter whether the annotation is added or not . Add this annotation to make the compiler better able to check . If you're not writing a functional interface , But with it @FunctionInterface, Then the compiler will report an error .

5、@FunctionalInterface Annotated interface. Its characteristic is that only one subclass must be implemented abstract Method .

Use scenarios

Callable、Runnable When you wait, you can use it .

@FunctionalInterface
    public interface Callable<V> {
        V call() throws Exception;
    }
    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }

Deprecated

Used to identify a method or class , Identifies that the class or method is obsolete , Not recommended .

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    public @interface Deprecated {
    }

The range of use is wide , Construction method 、 Field 、 Such method .

Be careful : It's just that the cue is out of date , Not recommended , Doesn't mean you can't use , But if we want to use a method or class marked with this annotation , It is suggested to find out if there is any alternative , There is no alternative , Find out why it's set to be obsolete , Improper use may cause unexpected problems to our program , It's also possible to dig holes .

Custom annotation

Finally came the custom , Let's define an annotation from here .

Use @interface When customizing annotations , Automatically inherited java.lang.annotation.Annotation Interface , Other details are done automatically by the compiler . When defining annotations , Cannot inherit other annotations or interfaces .@interface Used to declare an annotation , Each of these methods actually declares a configuration parameter . The name of the method is the name of the parameter , The return value type is the type of the parameter ( The return value type can only be a base type 、Class、String、enum). Can pass default To declare the default value of the parameter .

Format

public @interface  Annotation name  { Definable body }

Case study

Customize our annotations

@Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface  MyInterface {
        String value() default "";
    }

The use phase is the running phase , The goal is in the way . Define an attribute value The default value is an empty string .

Let's use our defined annotations .

import java.lang.reflect.Method;
    
    public class InterfaceDemo {
    
        //@MyInterface(" Laotian's custom annotation ")
         //@MyInterface
        @MyInterface(value = " Laotian's custom annotation ")
        public void test() {
            // TODO:
        }
    
        public static void main(String[] args) {
            InterfaceDemo interfaceDemo = new InterfaceDemo();
            Class<?> clazz = interfaceDemo.getClass();
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if ("test".contentEquals(method.getName())) {
                    System.out.println(" Method name = " + method.getName());
                    MyInterface myInterface = method.getAnnotation(MyInterface.class);
                    System.out.println(" Comments on methods = " + myInterface);
                    System.out.println(" Enumerated values = " + myInterface.value());
                }
            }
        }
    }

If not specified value Value , Then use the default value ,value There are two ways to assign values :

@MyInterface(" Laotian's custom annotation ")
    @MyInterface(value = " Laotian's custom annotation ")

Then we run the code above , The output is :

 

 

So we've done the custom annotation and the use of , Get attribute value .

Is annotation a normal class or an interface ?

Use javap Check out our custom annotations .class The contents of the document .

 

 

here Annotation It's the interface :

public interface Annotation {
    }

Then prove , Our custom annotation is extend Interface Annotation, From this we can see that annotations are interfaces .

Note on custom annotation

Supported data types of solution parameters :

  • All basic data types (int,float,boolean,byte,double,char,long,short)
  • String type
  • Class type
  • enum type
  • Annotation type
  • All the above types of arrays

Annotation How to set the parameters in it :

  • Only use public Or default (default) These two access modifications . for example ,String value(); Set the method here to defaul Default type .
  • Parameter members can only use primitive types byte,short,char,int,long,float,double,boolean Eight basic data types and String,Enum,Class,annotations And so on , And these types of arrays . for example ,String value(); The parameter member here is String.
  • If there is only one parameter member , It is better to set the parameter name to "value", Add parentheses . example : The following example FruitName Annotations have only one parameter member .

How to get annotations ?

There are five ways :

  1. Gets the annotations on the class :Class Class getAnnotation()
  2. Get comments on methods :Method Class getAnnotation()
  3. Get the annotation on the field :Field Class getAnnotation()
  4. Get the annotation on the constructor :Constructor Class getAnnotation()
  5. Get the annotation on the package :Package Class getAnnotation()

If the specified annotation type exists on this element , This method returns the comment of the element , Otherwise return to null. From the above concentration mode, we can find that , Is to use getAnnotation() Method acquired , I believe most people can guess why it is the same method name .

Let's talk about Java The originator of annotation acquisition in :

java.lang.reflect.AnnotatedElement

All methods of this interface

 

 

have a look AnnotatedElement Class diagram :

 

 

Find the class that gets the annotation mentioned above , It's all done AnnotatedElement Interface .

So the program gets the... Of a class through reflection AnnotatedElement After object , The method of the program can be called .

Here are four ways to visit Annotation Information :

「getAnnotation」

Returns the... That exists on the program element 、 Specifies the type of annotation , If the type annotation does not exist , Then return to null.

「getAnnotations」

Returns all comments that exist on the program element .

「isAnnotationPresent」

Determine whether the program element contains annotations of the specified type , To be is to return true, Otherwise return to false.

「getDeclaredAnnotations」

Returns all comments that exist directly on this element . Unlike other methods in this interface , This method ignores inherited comments .( If there is no comment directly on this element , Then return an array of zero length .) The caller of this method can modify the returned array at will ; This has no effect on the array returned by other callers

summary

Why learn to annotate ? What are the meta notes ? What are the basic notes ? How to customize annotations ? Is annotation a normal class or an interface ? What do you need to pay attention to when customizing annotations ? Get the annotation ?

版权声明
本文为[Tian Weichang]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201206143600366n.html