常见三种
@Override
子类覆写父类方法的声明注解(准确覆写)
@Deprecated
声明过时的方法,使用过时的方法会有条横线例如:method()(也可以翻译成:弃用)
@SuppressWarning
压制警告的注解(在知道警告但执意要执行的时候可以用该注解让警告信息不再出现)
P.s. 这三个都是编译时注解
注解分类
按照生命周期分:源码注解,编译时注解,运行时注解
按提供注解的来源分:JDK自带的注解,第三方框架的注解,我们自定义的注解,元注解
自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface TestAnnocation01 {
String v1();
String v2();
int v3() default 20;
}
注解用@interface表示
注解成员必须无参数无异常声明,可以用default设置默认值
(成员类型可以是基本类型+String+Class+Annotation+Enumeration)
(只有一个成员的情况下,成员名取value(),在使用过程中可以省略成员名和=号)
(可以没有成员,这样就是一个标识注解)
上面四个元注解分别为:作用域,注解类型,允许子类继承注解,生成的javadoc文档包含注解信息
作用域:
@Target | 表示该注解可以用于什么地方,可能的ElementType参数有: CONSTRUCTOR:构造器的声明 FIELD:域声明(包括enum实例) LOCAL_VARIABLE:局部变量声明 METHOD:方法声明 PACKAGE:包声明 PARAMETER:参数声明 TYPE:类、接口(包括注解类型)或enum声明 |
注解类型:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。 (自己看看,没啥用)
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。 (影响代码编译后的结果)
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们,并且可以在运行阶段起作用,还会影响代码的逻辑。(通过反射获取注解信息)(注解影响运行时的代码逻辑)
元注解
上面四种@Retention、@Documented、@Target、@Inherited
和新加入的@Repeatable共计5种
上面四种就不介绍了,重点说下@Repeatable,用于同一个注解多次使用的场景
//注解集
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {
Person[] value();
}
//注解集的子项
@Repeatable(Persons.class)
public @interface Person{
String role() default "";
}
//使用注解的类
@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man {
String name="";
}
//反射获取注解信息
if(Man.class.isAnnotationPresent(Persons.class)) {
System.out.println(Man.class.getAnnotations().length;
Persons p2=Man.class.getAnnotation(Persons.class);
for(Person t:p2.value()){
System.out.println(t.role());
}
}
注解的使用
@注解名(成员1=value1,成员2=value2)
解析注解
用反射在运行时获取注解信息,动态控制程序运行逻辑(用于解析运行时注解)
示例代码:
//通过反射获得类的方法,然后获取方法上声明的注解
public class Test01 {
@TestAnnocation01(v1 = "1", v2 = "2")
public void method(){
System.out.println("test01");
}
}
//通过反射获得类的方法,再获取方法上声明的注解
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("开始");
try {
Class<?> c =Class.forName("t1.Test01");
boolean b=c.getMethod("method", null).isAnnotationPresent(TestAnnocation01.class);
if (b) {
TestAnnocation01 t1=(TestAnnocation01) c.getMethod("method", null).getAnnotation(TestAnnocation01.class);
System.out.println(t1.v1());
System.out.println(t1.toString());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}