注解
annotations
注解是一种数据形式,也被称为元数据,它提供关于程序的数据,但是不是程序的一部分,对其所注解的代码没有直接的影响
- 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
- 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE 中注解占据了更重要的角 色,例如用来配置应用程序的任何切面,代替 java EE 旧版中所遗留的繁冗代码和 XML 配置等。
注解的用途:
- 对于编译器:编译器可以使用注解检测错误或取消警告
- 在编译或部署的时候:软件工具可以处理注解信息,生成代码、 XML 文件等
- 运行的时候:有些注解可在运行时检查
注解基础
注解的格式
@AnnotationName(element = "value")
-
如果注解没有元素,可以省略小括号
-
可以使用多个注解
@Author(name = "Jane Doe") @EBook class MyClass { ... }
-
可以重复注解
@Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }
注解类型
- 可以是java.lang或java.lang.annotation中预定义的
- 也可以是自己定义的
注解的位置
注解可以应用于声明: 类、字段、方法和其他程序元素的声明。
当在声明中使用时,每个注释通常按照惯例出现在它自己的行上。
在javase8中,也可以用于类型注释
eg
//Class instance creation expression: 类实例创建表达式:
new @Interned MyObject();
//Type cast: 类型转换:
myString = (@NonNull String) str;
//implements clause: 条款:
class UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
//Thrown exception declaration: 抛出的异常声明:
void monitorTemperature() throws
@Critical TemperatureException { ... }
声明注解
许多注解代替了代码中的注释
传统的注释
public class Generation3List extends Generation2List {
// Author: John Doe
// Date: 3/17/2002
// Current revision: 6
// Last modified: 4/12/2004
// By: Jane Doe
// Reviewers: Alice, Bill, Cindy
// class code goes here
}
注解方式
-
首先定义接口
@interface ClassPreamble { String author(); String date(); int currentRevision() default 1; String lastModified() default "N/A"; String lastModifiedBy() default "N/A"; // Note use of array String[] reviewers(); }
-
使用注解
@Documented//想要@ClassPreamble出现在 javadoc 生成的文档中,则必须添加@Document @ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation reviewers = {"Alice", "Bob", "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here }
预定义的注解
在 java.lang 中定义的预定义注释类型是@Deprecated、@override 和@SuppressWarnings。
@Deprecated
用于表示某个程序元素(类, 方法等)已过时,可以做版本升级过渡使用
一般和文档注释搭配使用@deprecated
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
@Override
重写父类的方法
- 添加之后,编译器会检查重写是否正确
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@interface不是接口,是注解类
@SuppressWarnings
抑制编译器警告
当我们不希望看到这些警告的时候,可以使用 SuppressWarnings 注解来抑制警告信息 , 在{“”} 中,可以写入你希望抑制(不显示)警告信
实例 @SuppressWarnings({“all"}),抑制所有的警告相关参数
关于 SuppressWarnings 作用范围是和你放置的位置相关 // 比如 @SuppressWarnings 放置在 main 方法,那么抑制警告的范围就是 main
@SafeVarargs
当应用于方法或构造函数时,@safevarargs@SafeVarargs 注释声明代码不会对其 varargs 参数执行可能不安全的操作。当使用此注解类型时,与 varargs 使用相关的未检查警告将被禁止。
@FunctionalInterface
适用于注解的注解
元注解,主要用于看源码的时候,本身用处不大
@Retention
保留
指定注解的作用范围,三种
- SOURCE(编译后丢弃)
- CLASS(保留到.class文件中,运行时不保留,默认的)
- RUNTIME(保留到.class文件中,运行时保留)
@Documented
指定该注解是否会在 javadoc 体现
@Target
指定注解可以在哪些地方使用 ,@Target说明了Annotation所修饰的对象范围
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
eg. ElementType.CONSTRUCTOR
can be applied to a constructor.可以用于构造函数
取值(ElementType)有
public enum ElementType {
/**用于描述类、接口(包括注解类型) 或enum声明 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
@Inherited
子类会继承父类注解
解析
注解只有被解析之后才会生效,常见的解析方法有两种:
- 编译期直接扫描 :编译器在编译 Java 代码的时候扫描对应的注解并处理,比如某个方法使用
@Override
注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。 - 运行期通过反射处理 :像框架中自带的注解(比如 Spring 框架的
@Value
、@Component
)都是通过反射来进行处理的。