注解Annotation是一种引用数据类型,编译之后也是生成xxx.class文件。
@Target(value = {ElementType.METHOD,ElementType.CONSTRUCTOR}) // 指定 可以标注的位置
@Documented
被标注的注解会被javadoc工具记录.被javadoc之类的工具处理,注解类型信息会被包括在生成的文档中
默认情况下,javadoc是不包括注解的
若注解@B,被@Documented标注,则被@B修饰的类,生成文档时,会显示@B。如果没有被@Documented标注,最终生成的文档中不会显示@B
@Retention(RetentionPolicy.SOURCE) // 表示最终不会编译成 class 文件
@Retention(RetentionPolicy.CLASS) // 最终编译为 class 文件
@Retention(RetentionPolicy.RUNTIME) // 最终编译为 class 文件, 并且可以被反射机制读取
@Deprecated // 标注已过时, 有更好的方案 ( 只是起一个标注信息的作用, 被标注的东西仍然还可以用 )
自定义注解
public @interface MyAnnotation {
/**
* 可以在 注解中定义属性
* 看着像个方法, 实际为属性
* @return
*/
String name();
/**
* 颜色属性
*/
String color();
/**
* 年龄属性
*/
int age() default 25; // 指定默认值
}
// 使用注解的时候, 必须给没有设置默认值的属性赋值
@MyAnnotation(name = "xxx",color = "blue")
public class lambdademo {
public static void main(String[] args){
}
}
如果注解中只有一个属性,并且属性名叫 value
的话,则使用该注解的时候,为属性赋值,可以不指定属性名。
如果注解中的某个属性是一个数组类型,且使用该注解,为该属性赋值的时候,大括号里只有一个值,则大括号可以省略。
public @interface Target {
ElementType[] value();
}
// 使用的时候, 大括号里只有一个元素, 大括号可以省略
@Target(ElementType.METHOD) 等同于 @Target({ElementType.METHOD})
反射提取注解
precondition
@Retention(RetentionPolicy.RUNTIME) // 必须要标注 Runtime, 才可以被反射机制读取
public @interface MyAnnotation {
String name();
String color();
}
Experimental subjects
@MyAnnotation(name = "on type", color = "red")
public class Cat {
@MyAnnotation(name = "on field", color = "blue")
private String name;
private Integer age;
private Integer sex;
}
Extraction by reflection
public static void main(String[] args) throws ClassNotFoundException {
Class<?> cls = Class.forName("com.itheima.Cat");
// 得到类上标注的 MyAnnotation
if(cls.isAnnotationPresent(MyAnnotation.class)){
System.out.println("======标注在类上的======");
MyAnnotation ano = cls.getAnnotation(MyAnnotation.class);
System.out.println(ano);
String color = ano.color(); // 得到 color 属性值
System.out.println(color);
}
// 得到属性上标注的 MyAnnotation
Field[] fields = cls.getDeclaredFields();
for(Field f : fields){
if(f.isAnnotationPresent(MyAnnotation.class)){
System.out.println("======标注在属性上的======");
System.out.println("被标注的属性 " + f.getName());
System.out.println(f.getAnnotation(MyAnnotation.class));
}
}
}
注解有啥用?
对程序的标记,通过反射可以获取到这个标记。
程序可以判断如果【类/方法/属性等等】上面有这个标记信息,就去做什么什么,如果没有,做什么什么。