java之注解
注解设计非常精巧,初学时觉得很另类甚至多余,甚至垃圾。有了java代码干嘛还要有@注解呢?但熟练之后你会赞叹,它竟然可以超越java代码的功能,让java代码瞬间变得强大。大家慢慢体会吧。注解可分为三类:JDK自带注解、元注解(描述注解的注解)、自定义注解(后面代码演示)。
JDK自带注解
- @Override(常用)
- @Deprecated标记就表明这个方法已经过时了,但我就要用,别提示我过期
- @SuppressWarnings(“deprecation”) 忽略警告
- @SafeVarargs jdk1.7出现,堆污染,不常用
- @FunctionallInterface jdk1.8出现,配合函数式编程拉姆达表达式,不常用
元注解
元注解:描述注解的注解。
- @Target 注解用在哪里:类上、方法上、属性上(常用)
- @Retention 注解的生命周期:源文件中、class文件中、运行中(常用)
- @Inherited 允许子注解继承
- @Documented 生成javadoc时会包含注解,不常用
- @Repeatable注解为可重复类型注解,可以在同一个地方多次使用,不常用
@Target ElementType.class
target英文译为:“目标”,即注解所在的位置,目标。它描述注解的使用范围:
- ElementType.ANNOTATION_TYPE 应用于注释类型
- ElementType.CONSTRUCTOR 应用于构造函数
- ElementType.FIELD 应用于字段或属性
- ElementType.LOCAL_VARIABLE 应用于局部变量
- ElementType.METHOD 应用于方法级
- ElementType.PACKAGE 应用于包声明
- ElementType.PARAMETER 应用于方法的参数
- ElementType.TYPE 应用于类的元素
@Retention RetentionPolicy.class
Retention英文译为“保留”,即注解保留的阶段,即注解的生命周期。某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中; 编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取。为何要分有没有呢?没有时,反射就拿不到,从而就无法去识别处理。
- SOURCE 在源文件中有效(即源文件保留)
- CLASS 在class文件中有效(即class保留)
- RUNTIME 在运行时有效(即运行时保留)
自定义注解
// 1、自定义注解 //@interface 注解名 //@Target(ElementType.TYPE) //2、指定注解存在的位置 TYPE可以出现在类上 @Target({ElementType.TYPE,ElementType.METHOD}) //13、注解可以出现在类上和方法上(类上、属性上和方法上任意组合) //@Target(value= {ElementType.TYPE,ElementType.METHOD}) //与上面效果相同 @Retention(RetentionPolicy.SOURCE) //3、指定注解的生命周期,SOURCE源码中生效 14、 生命周期只能有一个 @interface Test { // 4、给注解设置功能 // String name(); //6、注解里的一个属性,没有默认值,使用时需要赋值 String name() default "rose"; //8、注解里的一个属性,给属性一个默认值,使用是不需要赋值,使用方便 // 10、value是注解中的特殊属性,也需要给默认值或者手动赋值,手动赋值可以简写 String value(); } // 5、@Test() //没有任何属性时,可以直接 //7、@Test(name="java") // 给指定属性name赋值 //@Test // 9、因为name有属性值了,使用时就方便了 //@Test("hello") // 11、相当于 @Test(value="hello") @Test(name="zhangsan",value="hello") // 12、组合注解,name="zhangsan"是重新给name赋值 class Hello { // @Test // Test注解只能在类上使用 属性上不能用 String addr; // @Test // Test注解只能在类上使用 方法上不能用 @Test(name="lisi",value="hello") public void eat() { System.out.println("eating..."); } }