Recently, I have organized my personal study notes into a book, which includes Java basics, data structures, JVM, multi-threading, etc. Due to the limited space, only a few interview questions are shown below.

Friends in need can point to get:Click here to get it…

1. Basic grammar

The annotation definition looks a lot like the interface definition. In fact, like any other interface, annotations will be compiled into a class file.

@Target(ElementType.Method)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
Copy the code

Except for the @ symbol, @test is defined much like an empty interface. When defining annotations, you need meta-annotations, such as @target and @retention

@target is used to define where the annotation will be applied (such as to a method or field)

@Retention defines at what level annotations are available, in source (source), in class files (class), or at runtime (runtime)

In annotations, it is common to include elements that represent certain values. Programs can take advantage of these values when parsing annotations. Annotations without elements are called marker annotations.

ANNOTATION_TYPE: ElementType.ANNOTATION_TYPE: ElementType.ANNOTATION_TYPE: ElementType

annotations

instructions

@Target

The ElementType enumeration defines the CONSTRUCTOR declaration FIELD declaration (including enum instances) LOCAL_VARIABLE METHOD declaration PACKAGE: PARAMETER: TYPE: class, interface (including annotation TYPE), or enum declaration ANNOTATION_TYPE: annotation declaration (applied to another annotation) TYPE_PARAMETER: TYPE PARAMETER declaration (added in 1.8) TYPE_USE: PS: When the annotation does not specify a Target value, the annotation can use the type above any element

@Retention

This is defined by the RetentionPolicy enumeration. SOURCE: Annotations are discarded by the compiler (annotations of this type are discarded only in the SOURCE code after the SOURCE code is compiled, not in the compiled class file) Annotations are available in the class file, but are discarded by the VM (annotation information of this type remains in the source code and the class file, and is not loaded into the VIRTUAL machine (JVM) at execution time) RUNTIME: The VM will also retain annotation information at runtime, so annotation information can be read via reflection (source code, class file, and annotation information at execution time) PS: When annotations do not define a Retention value, the default value is class

@Documented

Presentation annotations are included in the javaapi document

@Inherited

An annotation that allows a subclass to inherit from its parent

2. Annotation elements

Annotation elements can be of the following types:

– all basic types (int, float, Boolean, byte, double, char, long, short)

– String

– Class

– enum

– the Annotation

– Arrays of the above types

If any other type is used, the compiler will report an error. No packaging type is allowed either. Annotations can also be used as element types, which means annotations can be nested.

Element modifier, can only be public or default.

– The default value is limited

The compiler is a bit picky about the default values for elements. First, elements cannot have indeterminate values. That is, an element must either have a default value or provide its value when using an annotation.

Second, for elements of non-primitive types, null cannot be used as a value, either when declared in source code or when default values are defined in the annotation interface. This limitation makes it difficult for the processor to represent the presence or absence of an element, because in each annotation declaration, all elements are present and have corresponding values. To get around this limitation, only special values can be defined, such as empty strings or negative numbers, to indicate that an element does not exist.

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

3. Shortcuts

What are shortcuts? Let’s take a look at the Controller annotation in springMVC

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { The default String value () ""; }Copy the code

You can see that Target applies to classes, interfaces, annotations, and enumerations. Retention policy is the RUNTIME RUNTIME and has a String value element. In common use, it basically looks like this:

@controller (" /your/path ") public class MockController {}Copy the code

That’s the shortcut, omitting the syntax of name-value pairs. Detailed explanation is given below:

The annotation defines an element named value, and if the element is the only one that needs to be assigned when the annotation is applied, the name-value pair syntax is not required. Instead, the required value of the value element is given in parentheses. This can be applied to any element of a legal type, but of course this limits the element name to value.

4. JDK1.8 annotations enhancement

TYPE_PARAMETER and TYPE_USE

In JDK1.8, ElementType has two more enumeration members, TYPE_PARAMETER and TYPE_USE, which are used to define which type can be annotated. For example, if you want to annotate the type parameters of a generic type:

public class AnnotationTypeParameter<@TestTypeParam T> {}
Copy the code

Then, when you define @testTypeParam, you must set elementType.type_parameter at @target, indicating that this annotation can be used to annotate type parameters. Such as:

@Target(ElementType.TYPE_PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestTypeParam 
{
}
Copy the code

Elementtype. TYPE_USE is used to annotate various types, so the above example can also change TYPE_PARAMETER to TYPE_USE, and an annotation is set to TYPE_USE, as long as the type name is annotated. For example, there is the following annotation definition:

@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
Copy the code

Then the following use annotations are ok:

List<@Test Comparable> list1 = new ArrayList<>();
List<? extends Comparable> list2 = new ArrayList<@Test Comparable>();
@Test String text;
text = (@Test String)new Object();
java.util. @Test Scanner console;
console = new java.util.@Test Scanner(System.in);
Copy the code

The @test annotation above is on the right side of the type. Be careful to distinguish between enumerators before 1.8. For example:

@Test java.lang.String text;
Copy the code

In the above example, it is clear that text is being used, so using the current @target would cause a compilation error and should include elementType.local_variable.

@ the Repeatable annotations

Repeatable @repeatable annotation is new in JDK1.8, you can guess its meaning from its name (Repeatable). You can repeat the same annotations in the same place. For example:

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

Annotate as follows:

@filter ({" /admin ", "/main"}) public class MainFilter {}Copy the code

For a change:

@filter (" /admin ") @filter (" /main ") public class MainFilter {}Copy the code

Before JDK1.8 came along, there was no way to reach this “style”. With 1.8, @filter could be defined as follows:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Filters.class) public @interface Filter {String value(); } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Filters {Filter [] value(); }Copy the code

This is actually an optimization by the compiler to use @repeatable to tell the compiler to use @filters as containers to collect Repeatable annotations while each @filter stores its own specified string value.

JDK1.8 in AnnotatedElement interface getDeclaredAnnotationsByType and getAnnotationsByType has been added, at a specified @ the annotation of the Repeatable, will be looking for repeat annotations in the container. In contrast, getDeclaredAnnotation and getAnnotation do not handle the @REPEATable annotation. Examples are as follows:

@filter (" /admin ") @filter ("/Filter ") public class FilterClass {public static void main(String[] args) { Class<FilterClass> filterClassClass = FilterClass.class; Filter[] annotationsByType = filterClassClass.getAnnotationsByType(Filter.class); if (annotationsByType ! = null) {for (Filter filter : annotationsByType) { System.out.println(filter.value()); } } System.out.println(filterClassClass.getAnnotation(Filter.class)); }}Copy the code

The log is as follows:

/admin
/filter
null
Copy the code

Biography: Swing unruly, love life. Java Cultivator (wechat official ID: Java Cultivator), welcome to follow. Access to 2000G of detailed information on the 2020 interview questions