注解 (Annotation)
也称注释,是一种引用数据类型,编译之后生成 xxx.class文件。
注解如何使用,用在什么地方?
- 注解使用的语法格式 @注解类型名
- 注解可以在类上、属性上、方法上、变量上等,也可以在注解上使用。
public class AnnotationTest {
public static void main(String[] args) {
}
@MyAnnotation
public void doSome() {
}
}
// 自定义注解
public @interface MyAnnotation {
}
Java内置注解
@Override
jdk 5.0 后的一个特性,标识性注解,是给编译器作参考的。
这个注解只能注解方法,在编译阶段,编译器看到方法上有这个注解,会自动检查该方法是否重写了父类的方法,如果没有重写,会报错。与运行阶段无关。
@Deprecated
用这个注解用来标注元素,表示这个元素已经过时。主要是向其它程序员传达一个信息,告知已过时,有更好的方案存在。
自定义注解
语法格式:
[修饰符列表] @interface 注解类型名{
}
public @interface MyAnnotation {
}
元注解
用来标注**“注解类型”的“注解”**
常见的元注解:
-
Target
Target注解用来标注“被标注的注解”可以出现在哪些方法上。
比如@Target(ElementType.METHOD) 表示“被标注的注解”只能出现在方法上。
-
Retention注解
Retention注解用来标注“被标注的注解”最终保存在哪里。
@Retention(RetentionPolicy.SOURCE) 表示该注解保存在java源文件中
@Retention(RetentionPolicy.CLASS) 表示该注解保存在class文件中
@Retention(RetentionPolicy.RUNTIME) 表示该注解保存在class文件中,并且可以被反射机制读取。
在注解中定义属性
public @interface MyAnnotation {
/**
* 在注解中可以定义属性,写法类似于方法
* 这个name就是MyAnnotation的一个属性
*/
String name();
String sex();
}
如果注解中有属性,那么在使用这个注解时,一定要给为属性赋值,否则会报错,除非这个属性使用default指定了默认值,默认值下面会讲到。
public class AnnotationTest {
public static void main(String[] args) {
}
// 注意,属性是什么类型值,就得赋什么类型的值
@MyAnnotation(name = "123", sex = "男")
public void doSome() {
}
}
默认值 default
public @interface MyAnnotation {
/**
* 在注解中可以定义属性,写法类似于方法
* 这个name就是MyAnnotation的一个属性
*/
String name();
int age() default 18;
}
value的省略
注解的属性名是value,并且只有一个属性时,属性名可以省略
public @interface MyAnnotation {
String value();
}
public class AnnotationTest {
public static void main(String[] args) {
}
@MyAnnotation("123")
public void doSome() {
}
}
属性是数组
public @interface MyAnnotation {
String [] name();
}
public class AnnotationTest {
@MyAnnotation(name = {"小明","小红","小美"})
public void doSome(){
}
/*
数组中只有一个值时,大括号可以省略
*/
@MyAnnotation(name = "小明")
public void doOther() {
}
}
对比源代码
Deprecated源代码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
Retention 是元注解,里面有一个名为value的属性值,该属性值的类型为枚举类型。所以在引用Retention注解时,可以省略value直接赋值。
Retention源代码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
RetentionPolicy源代码:
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
}
Target元注解中也有一个名为value的属性值,在引用时同样可以省略。
Target源代码:
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();
}