注解
1、什么是注解
注解:可以理解就是一个类,可以通过属性设置参数
2、注解有什么用
注解可以使用在包、类、字段、方法、局部变量、方法参数等,用来对这些元素进行说明。在开发过程中,使用xml配置文件内容过多,导致程序难以维护,将使用注解取代xml配置文件。
3、怎么使用注解
接下来我们要学习怎么去定义注解,使用注解,然后再去解析注解。
在这之前我们先来看看jdk5提供的常用注解有哪些。
@Override jdk1.5表示子类复写父类的方法;jdk1.6中表示实现接口方法以及复写父类的方法
@Deprecated 过时了,建议不再使用,但还可以使用。
@SuppressWarnings() 抑制警告,通知编译器不进行错误报警
"deprecation", 过时
"rawtypes", 没有泛型
"unused", 没有使用
"null" , 空指针
"serial" 序列号
"all" 所有
3.1 定义注解
- 定义语法:使用关键字@interface 来定义名叫Anno的注解
public @interface Anno {
}
-
属性格式:
[public abstract] 返回值类型 属性名() [default 默认值];返回值类型:基本类型(包装类型)、String、Class、注解、枚举enum 以及以上类型的一维数组属性名:自定义
public @interface Anno {
public abstract String username() default "";
public abstract long birthday();
int age();
Class clazz();
Color color() default Color.red;
Anno1 anno();
}
public @interface Anno1 {
String value();
}
public @interface Annos {
String[] value();
}
enum Color{
red(),
black()
}
3.2 使用注解
- 在指定的位置(类、方法、字段、构造等) 使用格式: @注解名称(属性名称=值, 名称2=值2)
属性名称:如果属性名称为value(eg:Anno1),使用时只有一对属性,此时value可以省略。
//@Anno1(value = "") @Anno1("") public void demo(){ }属性值:如果类型为数组(eg:Annos),需要使用{}进行扩展,多个值之间使用,进行分割;如果只有一个值,{}是可以省略的。
//@Annos(value={"1", "2", "3"}) //@Annos(value={"1"}) @Annos(value="1") public void demo1(){ }- 综合使用: 这里是使用在类上的注解,需要了解后面元注解的概念。
@Anno( username = "sxd", age = 18, birthday = 12345678, clazz = Date.class, anno = { @Anno1("666"), @Anno1(value = "888") } ) public class TestAnno { }
3.3 解析注解
我们将使用AnnotatedElement类下面的函数来解析注解
- getAnnotation(Class annotationClass) 通过指定的注解的字节码获得注解实例
- isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断当前对象上是否包含指定的注解
- getAnnotations() 获得所有的public的注解
- getDeclaredAnnotations() 获得所有的注解(包括private)
@Anno1
@Anno2
@Anno3(username="java",password="test")
public class TestAnno {
public static void main(String[] args) {
//解析
boolean a1 = TestAnno4.class.isAnnotationPresent(Anno1.class);
boolean a2 = TestAnno4.class.isAnnotationPresent(Anno2.class);
boolean a3 = TestAnno4.class.isAnnotationPresent(Anno3.class);
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
//获得数据
if(a3){
Anno4_3 anno = TestAnno4.class.getAnnotation(Anno4_3.class);
System.out.println(anno.username());
System.out.println(anno.password());
}
}
}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@interface Anno1{
}
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@interface Anno2{
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
//@Inherited //子类都继承
@interface Anno3{
String username();
String password();
}
4、元注解
- 元注解:用于修饰注解(自定义注解)的注解(JDK已经提供好的注解)。
-
@Retention 被修饰自定义注解的生命周期
- @Retention(RetentionPolicy.SOURCE) , 被修饰的自定义注解,只能在源码中存在。提供编译器使用
- @Retention(RetentionPolicy.CLASS), 被修饰的自定义注解,只能在源码和字节码中存在。提供JVM使用
- @Retention(RetentionPolicy.RUNTIME), 被修饰的自定义注解,只能在源码、字节码和运行时中存在。提供程序获得数据
-
@Target 被修饰自定义注解,使用的位置;下面几个是经常使用的
- @Target(ElementType.TYPE) 被修饰的自定义注解,只能在类或接口上使用
- @Target(ElementType.CONSTRUCTOR) 被修饰的自定义注解,只能在构造方法上使用
- @Target(ElementType.FIELD) 被修饰的自定义注解,只能在字段上使用
- @Target(ElementType.METHOD) 被修饰的自定义注解,只能在普通方法上使用
- @Documented 被修饰自定义注解,可以在javadoc生成的文档存在。
- @Inherited 被修饰的自定义注解,所有子类都将继承该注解
-