Annotations are often used no matter in Java background or Android development, the most commonly used is @Override. Many frameworks of processes use annotations as a functional mechanism, such as Spring and MyBatis commonly used in Java background development, Android Retrofit, etc. Butterknife, etc., are annotation frameworks. Notes are also often asked in interviews, but what do we know about the nature of notes? What are the categories? How to customize and use? How does it work? This article will give a comprehensive introduction.
I. Definition of annotations
Java annotations are used to provide metadata for 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.
In daily development, we use class and interface to create Java classes, and annotations are also a kind of type, using the @interface modifier
Purpose: Identifies/interprets Java code.
Second, annotation type
1. Meta-annotations
As the name implies, we can understand as the annotation of the annotation, it is used in the annotation, convenient for us to use the annotation to achieve the desired function. Meta annotations include @Retention, @target, @document, @Inherited and @REPEATable (added in JDK1.8).
@Retention
@retention (retentionPolicy.runtime)// Public @interface MyAnnotation {}Copy the code
Retention refers to the Retention phase in which annotations are retained in source code (compile-time), bytecode (class-load), or runtime (run in the JVM). Use the enumeration RetentionPolicy in the @Retention annotation to indicate the Retention policy for the annotation Retention period:
- @Retention(retentionPolicy.source), annotations exist only in the SOURCE code and are not included in class bytecode files
- @Retention(retentionPolicy.class), the default Retention policy. Annotations are present in the CLASS bytecode file but not available at runtime
- @Retention(retentionPolicy.runtime), annotations are stored in class bytecode files and can be retrieved by reflection at RUNTIME
@Target
@ Target ({ElementType. FIELD, ElementType METHOD}) / / multiple use {} enclosed, and then use a comma to open public @ interface MyAnnotation {}Copy the code
The @target meta-annotation is used to specify the scope of the annotation, which can be classes, methods, method parameters, and so on. It is also used to express the scope of the annotation through the enumeration class ElementType.
- @target (elementType.type) functions on interfaces, classes, enumerations, and annotations
- @target (elementType. FIELD) a constant used for attribute fields and enumerations
- @target (ElementType.METHOD) Specifies the action METHOD
- @target (elementtype.parameter) acts on method parameters
- @target (elementtype.constructor) acts on the CONSTRUCTOR
- @target (elementType.local_variable) acts on local variables
- @target (elementType.annotation_type) applies to annotations (this property is used in the @retention annotation)
- @target (elementType.package) applies to packages
- @target (elementtype.type_parameter) applies to type generics, i.e. generic methods, generic classes, generic interfaces (added in JDk1.8)
- The @target (elementType.type_use) type is used. Can be used to annotate any type except class (added in JDk1.8)
The most commonly used TYPE is elementType. TYPE.
@Documented
@target (elementType.field) @Retention(RetentionPolicy.runtime) Public @interface MyAnnotation {}Copy the code
Document means Document in English. It provides the ability to include elements from annotations into Javadoc.
@Inherited
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
}
Copy the code
When an annotation annotated by @Inherited modifs a parent class, its children inherit the same annotation. When an annotation annotated by @Inherited modifs a parent class, its children inherit the same annotation.
@MyAnnotation public class FatherClass { } public class SonClass extends FatherClass { } public class test { public static void main(String[] args){ Class<SonClass> sonClass = SonClass.class; MyAnnotation annotation =sonClass.getAnnotation(MyAnnotation.class); }}Copy the code
In the example above, the parent class is annotated with an inheritable annotation. The subclass is not annotated with the annotation, but the subclass gets the Mynnotation annotation successfully, indicating that the subclass inherits MyAnnotation from the parent class.
Repeatable @Repeatable means Repeatable. As the name implies, an annotation modified by this meta-annotation can apply to an object more than once, but each annotation can represent a different meaning.
Introduced in Java 1.8, annotations can take multiple values
The following is an example to illustrate its definition.
@rolecontainer // Container annotations are themselves annotations, @target (elementtype.type) @Retention(retentionPolicy.runtime) public @interface RoleContainer {Role[] value(); } @role ();} @role (); @repeatable (rolecontainer.class) @Retention(retentionPolicy.runtime) public @interface Role {Repeatable(rolecontainer.class) @Retention(retentionPolicy.runtime) public @interface Role { String role() default ""; } @role (annotated by @repeatable);} @role (annotated by @repeatable); @role (Role = "CEO") @role (Role = "Father") @role (Role = "husband") @role (Role = "son") public class Man {}Copy the code
2. Java built-in annotations
Definition: annotations that are already implemented in Java
There are five classes of built-in annotations in Java, including:
Deprecated: Deprecated annotation used to mark obsolete & Deprecated elements (classes, methods, etc.)
Override: Override annotation to indicate that the method needs to be overridden by a subclass
@SuppressWarnings: Block warning annotation. The element used for the tag prevents the compiler from issuing warning warnings
SafeVarargs: Parameter safety type annotation, used to remind developers not to do unsafe things with parameters & prevent compilers from generating unchecked warnings. Introduced after Java 1.7
ClassCastException is thrown at runtime, although no errors are reported at compile time. SafeVarargs // Not actually Safe! static void m(List<String>... stringLists) { Object[] array = stringLists; List<Integer> tmpList = Arrays.asList(42); array[0] = tmpList; // Semantically invalid, but compiles without warnings String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime! }Copy the code
@functionalInterface: FunctionalInterface = 1 plain Interface with 1 method, new in Java 1.8
@functionalInterface public interface Runnable {public abstract void run(); }Copy the code
3. Custom annotations
The next section explains how to customize annotations, as well as learning about annotation properties and how to get them.
3. Use of annotations
1. Define annotations
Define an annotation that takes the form of an interface, but prefixes interface with @ :
public @interface Role {
String role() default "";
}
Copy the code
2. Annotation properties
An annotation is essentially an Annotion interface.
/**Annotation */ public interface Annotation {Boolean equals(Object obj); int hashCode(); Class<? extends Annotation> annotationType(); }Copy the code
From the above source code, we know that annotations themselves are subinterfaces of the Annotation interface. In other words, annotations can have properties and methods, but the properties in the interface are static and final, which makes no sense for annotations. The method we define the interface is just like the properties of annotations. That’s why annotations only have attribute member variables, which are actually methods of the interface. That’s why member variables have parentheses. Unlike interfaces, we can assign values to member variables in parentheses.
Public @interface Role {// Annotation attribute, annotation only attribute, no method, method name = attribute name, method return value = attribute type String Role () default ""; int id(); Role(Role ="father",id =1); // If the annotation has only one attribute, "value" can be omitted Role("father").Copy the code
Annotation attribute types can have the following types listed:
- Basic data types
- String
- Enumerated type
- Annotation type
- The Class type
- A one-dimensional array type of the above type
3. Use annotations
The annotation can be used by prefixing the class/member variable/method definition with “@ annotation name”.
@role (Role = "CEO") public class Tony {}Copy the code
4. Get annotations
This is the key to using annotations, and the purpose of using annotations is to get the value of an annotation property. How do I get annotations? Java’s reflection technology, of course.
Using Java reflection can be time consuming, so you need to consider the performance impact of using running annotations.
Method of obtaining annotations:
Public Boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return GenericDeclaration.super.isAnnotationPresent(annotationClass); } public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { Objects.requireNonNull(annotationClass); return (A) annotationData().annotations.get(annotationClass); Public Annotation[] getAnnotations() {return AnnotationParser.toArray(annotationData().annotations); }Copy the code
Example of getting annotations and annotation properties:
@Retention(RetentionPolicy.RUNTIME) public @interface Role { String role() default ""; int id(); } @Role(role = "CEO", id = 1) public class Tony { @Role(role = "teacher", id = 2) public String son; @Role(role = "doctor", id = 3) public String getDaughter() { return "daughter is doctor"; }} public class TestAnnotation {public static void test() {Boolean isRoleAnnotation = Tony.class.isAnnotationPresent(Role.class); Log.d(TAG, "tony is decorated by RoleAnnotation:" + isRoleAnnotation); Role roleAnnotation = tony.class.getannotation (role-.class); if (roleAnnotation ! = null) { Log.d(TAG, "tony role is " + roleAnnotation.role()); Class<Tony> Tony = tony.class; try { Field field = tony.getField("son"); roleAnnotation = field.getAnnotation(Role.class); if (roleAnnotation ! = null) { Log.d(TAG, "field role is " + roleAnnotation.role()); } Method method = tony.getDeclaredMethod("getDaughter"); roleAnnotation = field.getAnnotation(Role.class); if (roleAnnotation ! = null) { Log.d(TAG, "method role is " + roleAnnotation.role()); } } catch (Exception e) { } } }Copy the code
Print result:
D/TestAnnotation: tony is decorated by RoleAnnotation:true
D/TestAnnotation: tony role is CEO
D/TestAnnotation: field role is teacher
D/TestAnnotation: method role is teacher
Copy the code
Fourth, the application of annotations
According to the Retention attribute of annotations, their application can be divided into three scenarios:
- Provide information to the compiler: The compiler can use annotations to detect errors or warnings and print a log.
- Compile-time processing: Software tools can use annotation information to automatically generate code, documentation, or other corresponding automated processing.
- Runtime processing: Some annotations accept code extraction while the program is running and do so automatically.
Application, for example,
Application Scenario 1: Test code
For example, the well-known testing framework JUnit = uses annotations for code testing.
public class ExampleUnitTest { @Test public void Method() throws Exception { ... }} // @test marks the Method to be tested.Copy the code
Application Scenario 2: Decouple & simplify code to improve development efficiency
ButterKnife, the well-known IOC framework for Android development, reduces a lot of repetitive code.
public class TestActivity extends AppCompatActivity {
@BindView(R.id.tvTest)
TextView tvTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ButterKnife.bind(this);
}
Copy the code
Retrofit, an awesome Http network access framework, uses annotations to describe network request parameters:
public interface UserService {
@GET("users/all")
Call<List<UserInfo>> listUsers();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://xxx.com/")
.build();
UserService userService = retrofit.create(UserService.class)
Call<Response<List<UserInfo>>> call = userService.listUsers();
Copy the code
5. How annotations work
Handle — APT at compile time
Compile-time processing requires the use of APT technology, which provides a compile-time annotation processing flow.
The annotations of the.java file are scanned at compile time and passed to the annotation processor, which generates new.java files from the annotations. These new.Java questions are compiled by Javac along with the original.java.
Annotation handler is a tool that handles annotations at javAC compile time. You can create annotation handlers and register them. At compile time, the handlers you create take Java code as input and generate files as output. Annotation handlers cannot modify existing Java classes, only generate new ones.
Runtime processing uses reflection to process runtime annotations. For reflection, runtime annotations use reflection to retrieve attributes and methods decorated with annotations.
Six, often meet test questions
-
Q1: What are comments? What are their typical use cases?
Metadata for program source code elements, code markers, compiler information, compile-time and deploy-time processing, and run-time processing.
-
Q2: Describe some useful comments from the standard library.
@ Override etc.
-
Q3: How can you create a comment?
@interface
-
Q4: What object types can be returned from annotated method declarations?
Basic, String, Class, Enum, or array of the preceding type. Object is not supported.
-
Q5: Which program elements can be commented out?
Class, constructor, method, field
-
Q6: Is there a way to limit the elements to which annotations can be applied?
@Target
-
Q7: What is a meta-comment?
Notes of notes
-
Q8: What are repeated comments?
Repeatable can be applied multiple times to annotations of the same element declaration
-
Q9: How can you retrieve comments? What does this have to do with reservations?
reflection
-
Q10: Can COMMENTS be extended?
Annotations extend annotations, but annotations do not extend
Seven,
Annotations are common in our development, and being able to use annotations is a skill we must master. This paper summarizes the definition and type of annotations, how to customize and use annotations, the working principle of annotations, and application scenarios. The use of annotations can improve development efficiency and write elegant code, but it is also important to note that running annotations brings performance problems and requires a thorough understanding of the principles of annotations and their use.
Pay attention to the public number “code farmers turn over record”, reply 888, free technical information. After paying attention, you will receive high quality technology and job sharing from time to time, I hope to accompany you to move forward with your dream.