1、Annotation 概念
Annotation 注解,标注。(JDK 1.5 引入的一种注释机制)。
通俗理解:
注解就是一种通过在类、方法或者属性等上使用类似@XXX的方式进行打标签,然后再通过一些手段对标签进行解析和处理的技术手段。说白了就是一种特殊的标签。
Java 内置了10 个注解 :
作用在代码上的注解(3个),在 java.lang 包下,分别是:@Overide(方法重载)、@Deprecated(过时、弃用)、@SuppressWarnings(忽略警告)
作用在注解上的注解 ( 即 元注解 ) 4个,在 java.lang.annotation 包下,分别是:@Target (目标)、@Retention(保留期) 、@Documented(文档)、@Inherited(继承)
Java 7 之后新增加的注解 (3个) : 在 java.lang 包下,分别是:@FunctionalInterface (函数接口)、@SafeVarargs(安全)
在 java.lang.annotation 包下, @Repeatable (重复声明)
接下来我们从思维导图和源码来系统的认识一下Annotation:
Annotation体系框架图.png1.1 作用在代码上的注解:
1.1.1 @Override: 标识该方法是重写父类的方法
/**
*Indicates that a method declaration is intended to override a method declaration in a supertype.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
1.1.2 @Deprecated: 标识该方法或者类已经被弃用,建议不要使用
/**
*A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous,or *because a better alternative exists.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
1.1.3 @SuppressWarnings: 指示编译器去忽略注解中声明的警告
/**
* Indicates that the named compiler warnings should be suppressed in the
* annotated element (and in all program elements contained in the annotated
* element).
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
1.2 作用在注解上的注解(元注解)
1.2.1@Target: 用于标记该注解会被用在什么地方。
/**
* Where Annotations My Appear
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
* @since 1.8
*/
TYPE_USE
}
1.2.2 @ Retention 标记这个注解的"寿命".
有三种:SOURCE--代码中,,编译器会忽略、 CLASS---class 文件中,JVM会忽略、 RUNTIME---运行时
CLASS 包含了 SOURCE ,RUNTIME 包含了CLASS ,SOURCE
/**
* Indicates how long annotations with the annotated type are to
* be retained. If no Retention annotation is present on
* an annotation type declaration, the retention policy defaults to
* {@code RetentionPolicy.CLASS}.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
/**
* retention的属性值
*/
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
1.2.3 @Documented 标记注解包含在用户文档中
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
1.2.4 @Inherited 允许子类继承父类中的注解
/**
* Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
1.3 新增的注解
1.3.1 @SafeVarargs 忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告
/**
* A programmer assertion that the body of the annotated method or
* constructor does not perform potentially unsafe operations on its
* varargs parameter.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}
1.3.2 @FunctionalInterface 标识一个匿名函数或函数式接口
/**
* An informative annotation type used to indicate that an interface
* type declaration is intended to be a <i>functional interface</i> as
* defined by the Java Language Specification.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
1.3.3 @Repeatable 标识某注解可以在同一个声明上使用多次
/**
* The annotation type {@code java.lang.annotation.Repeatable} is
* used to indicate that the annotation type whose declaration it
* (meta-)annotates is <em>repeatable</em>. The value of
* {@code @Repeatable} indicates the <em>containing annotation
* type</em> for the repeatable annotation type.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
/**
* Indicates the <em>containing annotation type</em> for the
* repeatable annotation type.
* @return the containing annotation type
*/
Class<? extends Annotation> value();
}
2.Annotation 对应关系
Annotation 关系对应图 从上面架构图可以看出:
一个Annotation 和 一个RetentionPolicy 关联,即每一个Annotation对象有且只有一个RetentionPolicy属性。
一个Annotation 和 1~n个ElementType 关联,即每一个Annotation对象可以用 大于等于 1个的ElementType属性。
因为Annotation是一个接口,那么他的实现类,全部都满足1,2 两条的关联关系。
3.Annotation 使用场景
Annotation 是一个辅助类,我们经常使用到的有:
- 如果RetentionPolicy == SOURCE时,为编译器进行编译语法检查,APT等场景
- RetentionPolicy == CLASS时,会保留在class文件中,会被虚拟机忽略。此时完全符合的场景是字节码操作:AspectJ 、热修复Roubust等;
- 如果RetentionPolicy == RUNTIME 时,则我们可以在反射中解析并使用;
- 如果使用@Documented注解,可以使该注解出现在javadoc中,生成帮助文档
- 通过注解方便了解代码结构
知识点:
1)APT (Annotation Processor Tools) ,注解处理器,用于处理注解。编写好的java源文件,经过javac编译后翻译为虚拟机能够加载解析的字节码Class 文件。注解处理器用来在编译时期扫描处理注解信息。你可以为某些注解注册自己的注解处理器,此注解处理器由javaC调起,并将注解信息传递给注解处理器进行处理。更多关于注解处理器在后续的文章中详细介绍。
2)所谓字节码操作,就是直接修改字节码Class文件以达到修改代码执行逻辑的目的。
4.Annotation 自定义
下面我们来简单的自定义个Annotation:
package com.leon.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int viewId();
}
说明:
1)注解是使用@interface 来定义的,其实和接口很像,但是@是必须的
2)接口的参数定义如:int viewId (); 和类的成员变量类似,但是必须要带上圆括号“()”
3)如果要给参数设置默认值,则直接在圆括号之后,f分号之前 加上 default XXX。 如: int viewId() default 0;
4)@Target 注解里面可以有多个值(参考第二点的对应关系),如:@Target({ElementType.FIELD,ElementType.LOCAL_VARIABLE})
5)如果注解只有一个参数,最好取名value ,这样可以在使用的时候注解指定属性值
6)只能使用public和默认权限修饰符来修饰参数
7)注解参数必须有确定的值。在定义的时候给默认值或在使用的时候指定参数值
注解如果没有注解处理器来解析他,那么注解也没什么作用,那我们该怎么使用注解来完成一些工作呢? 杰西莱的文章中介绍。
今天就到此结束了,欢迎各位留言评论。
网友评论