了解和入门注解的应用
注解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你在包,类,字段,方法,方法的参数以及局部变量上。
java.lang 包 中jdk的几个基本注解:
Deprecated
Override
SuppressWarnings
在使用过期的方法时,会出现删除线:
使用过期的方法,进行编译时会进行提示,如果不想编译器提示,可以使用 @SuppressWarnings("deprecation") 编译器就不会提示
1. @Deprecated 标示过时的方法
public class AnnotationTest { public static void main(String[] args) { AnnotationTest.sayHello(); } @Deprecated public static void sayHello(){ System.out.println("say Hello"); } }
2.@Override 表示对父类的覆盖
3.@Retention
定义一个注解
@Retention(RetentionPolicy.RUNTIME) public @interface ItcastAnnotation { }
注解的声明周期有三个阶段:
java源文件-->class文件-->内存中的字节码
javac把java源文件翻译成class文件时有可能去掉注解
类加载器把class文件调到内存中时也有可能去掉注解
在声明注解时可以添加@Retention,来表明声明周期在哪个阶段,其三种取值:RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME
默认值在Class阶段
如果不声明RetentionPolicy.RUNTIME
如下的if是不会执行的
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){ //注解的反射调用 ItcastAnnotation annotation = AnnotationTest.class.getAnnotation(ItcastAnnotation.class); System.out.println(annotation); }
因为AnnotationTest.class 得到了字节码,在检查字节码上有没有这个注解时(isAnnotationPresent),由于注解的默认保留在class文件当中的,当调到内存中时是没有的,AnnotationTest.class 代表内存的二进制,所以找不到注解
添加RetentionPolicy.RUNTIME 后可以进入if方法
@Override是给编译器看的,保留在 RetentionPolicy.SOURCE阶段
@SuppressWarnings是给编译器看的,保留在 RetentionPolicy.SOURCE阶段
@Deprecated 保留在RetentionPolicy.RUNTIME阶段
4.可以在注解中声明@Target,表示注解使用的场景
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.TYPE}) public @interface ItcastAnnotation { }
ElementType.METHOD 表示注解使用在方法上, ElementType.TYPE 表示注解可以使用在Class,interface,enum上
Enum Constant Summary ANNOTATION_TYPE Annotation type declaration CONSTRUCTOR Constructor declaration FIELD Field declaration (includes enum constants) LOCAL_VARIABLE Local variable declaration METHOD Method declaration PACKAGE Package declaration PARAMETER Parameter declaration TYPE Class, interface (including annotation type), or enum declaration
5.为注解增加各种属性
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.TYPE}) public @interface ItcastAnnotation { String color() default "blue"; //为属性设置默认值 String value(); //特殊的属性,在使用时可以直接设置值,不用谢value="" }
@ItcastAnnotation(color="red",value = "xyz") //为注解的属性设值 public class AnnotationTest { public static void main(String[] args) { // AnnotationTest.sayHello(); if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){ ItcastAnnotation annotation = AnnotationTest.class.getAnnotation(ItcastAnnotation.class); System.out.println(annotation); System.out.println(annotation.color()); //获取注解的属性值 } } @ItcastAnnotation("xyz") //属性名称叫value时,可直接写入值 @Deprecated public static void sayHello(){ System.out.println("say Hello"); } }
为注解增加高级属性
增加数组属性
@Retention(RetentionPolicy.RUNTIME) //元注解,注解的注解 @Target({ElementType.METHOD,ElementType.TYPE}) public @interface ItcastAnnotation { String color() default "blue"; //为属性设置默认值 String value(); //特殊的属性,在使用时可以直接设置值,不用谢value="" int[] arrayAttr() default {3,4,5}; //增加数组属性 }
@ItcastAnnotation(color="red",value = "xyz",arrayAttr={1,2,3})
如果数组属性中只有一个元素,这时候属性值部分可以省略大括号
枚举类型的属性:
@Retention(RetentionPolicy.RUNTIME) //元注解,注解的注解 @Target({ElementType.METHOD,ElementType.TYPE}) public @interface ItcastAnnotation { String color() default "blue"; //为属性设置默认值 String value(); //特殊的属性,在使用时可以直接设置值,不用谢value="" int[] arrayAttr() default {3,4,5}; //增加数组属性 TrafficLamp lamp() default TrafficLamp.RED; //使用枚举 }
System.out.println(annotation.lamp().nextLamp());
使用注解作为属性
@Retention(RetentionPolicy.RUNTIME) //元注解,注解的注解
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
String color() default "blue"; //为属性设置默认值
String value(); //特殊的属性,在使用时可以直接设置值,不用谢value=""
int[] arrayAttr() default {3,4,5}; //增加数组属性
TrafficLamp lamp() default TrafficLamp.RED; //使用枚举
MetaAnnotation annotation() default @MetaAnnotation("123"); //使用注解作为属性
}
@ItcastAnnotation(annotation=@MetaAnnotation("abc"),color="red",value = "xyz",arrayAttr={1,2,3})
System.out.println(annotation.annotation().value()); //abc