Java 中的注解有哪些?如何自定义注解?(高级岗位必背)
熟悉 C#的人应该知道,C#中的 Attribute 类,实现对元数据(数据的数据)的编程支持。
Java 也是个要面子的语言,迫不得已之下,也在 java1.5 的时候,搞了一个注解(Annotation)出来。有图为证。

注解的概念
白话的说,注解就是修饰类,方法,属性,参数等元素的一个标注,它本身不包含任何逻辑,只是标注了这些信息,标注给谁看呢?有些标注是给编译器看,提醒编译器编译时要区别对待一下。有些标注给 JVM 看,JVM 在运行的时候要注意这个标注是不是有新的行为要触发。
Java 自带的标注
jdk1.8,自带了 5 种标注。
- @SuppressWarnings —— 这个标记是给编译器看的,编译的时候就不会再出现警告信息。
- @Override —— 强制一个子类必须覆盖父类的方法
- @Deprecated —— 标记某个元素已经过时,这个是给编译器看的,编译的时候就会给出警告。
- @SafeVarargs —— Java 会对堆污染的方法编译警告,这个标注是压制这个警告。
- @FunctionInterface —— Java8 新增的,用于标注某个接口必须是函数式接口。可参考 《java-8-中的拉姆达表达式是什么?》
这 5 种标注的更详细信息,可以自行查看其 API。
注解的注解——元注解
搞笑的是,我们在定义注解的时候,还需要用到别的注解。这种注解就叫元注解。
自带的元注解有 5 种:
- @Retention
- @Target
- @Document
- @Inherited
- @Repeatable
@Retention 修饰这个注解可以在何时被看到,有 3 种策略,
- RetentionPolicy.CLASS 这是默认策略。这种策略下,注解在与.class 文件中,运行时 JVM 无法看到它。
- RetentionPolicy.SOURCE 这种策略中,不存在.class 文件,更不能运行时可见,只能在源码中看到。
- RetentionPolicy.RUNTIME 这种策略下可以在运行时访问到。通常情况下,我们都会结合反射来做一些事情。
@Target 可以选择的参数值有如下这些:
- ElementType.ANNOTATION_TYPE(注:修饰注解)
- ElementType.CONSTRUCTOR
- ElementType.FIELD
- ElementType.LOCAL_VARIABLE
- ElementType.METHOD
- ElementType.PACKAGE
- ElementType.PARAMETER
- ElementType.TYPE(注:任何类型,即上面的的类型都可以修饰)
@Document 标注过的注解 A,在使用了注解 A 后,javadoc 工具在生成文档的时候,会把注解 A 的信息放在文档中。
@Inherited 标注过的注解 A,父类中使用 A 注解后,子类也会自动的继承了 A 注解。
java.lang.annotation.Inherited
@Inherited
public @interface MyAnnotation {
}
@MyAnnotation
public class MySuperClass { ... }
public class MySubClass extends MySuperClass { ... }
复制
上述代码,子类通过继承也有了 MyAnnotation 注解。
@Repeatable 是 Java8 中新增的注解,使得代码可读性更好点,看一个例子理解它的用途。
没有用@Repeatable 的时候
public @interface Authority {
String role();
}
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseOldVersion {
@Authorities({@Authority(role="Admin"),@Authority(role="Manager")})
public void doSomeThing(){
}
}
复制
使用@Repeatable 的时候
@Repeatable(Authorities.class)
public @interface Authority {
String role();
}
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseNewVersion {
@Authority(role="Admin")
@Authority(role="Manager")
public void doSomeThing(){ }
}
复制
那么如何自定义一个注解,参考 java 中如何自定义注解?/