Java注解提供一种为程序元素设置元数据的方法,注解不影响程序代码的运行,添加或者删除注解代码都应该可以运行。注解是从jdk1.5开始引入的。注解是一个接口,程序可以通过反射来获取指定程序中元素的Annotaion对象,然后通过这个对象来获取注解中的元数据信息。
JDK提供的注解
jdk原生提供了一些元注解和标准注解。此外、开发人员可以自定义注解。
元注解
元注解就是注解的注解,用来注释其他的注解,有以下几个:
- @Target(ElementType.xxx) 说明其标注的注解可以用在什么地方,ElementType.TYPE是说注解是用在类上的,ElementType.FIELD是域也就是类成员变量,其他还有CONSTRUCTOR,LOCAL_VARIABLE局部变量,METHOD, PACKAGE等等
- @Retention(RetentionPolicy.xxx) 这个用来说明注解可以保存到什么级别,RetentionPolicy.SOURCE是编译的时候就么了被编译器丢弃、只在原代码里存在;CLASS是在class文件里有、但是jvm无视、默认是这个;RUNTIME是运行时也保留、可以通过反射机制读取注解信息,最常用的也是这个。
- @Documented 声明这个注解要保留到JavaDoc里边
- @Inhertied 子类要继承这个注解
其他几个标准注解
- @Override 编译时检查此处Override方法声明的正确性
- @Deprecated 注明这个是过期的应该被废弃的方法
- @SuppressWarning 关闭指定的警告信息
用反射获取注解中的元数据信息
如果不是有这个功能,那注解也就不会比注释更有用了,不是么。
看代码:
先创建两个注解
@Target(ElementType.FIELD) //给类里边的成员变量用
@Retention(RetentionPolicy.RUNTIME) //运行时可用
@Documented //将注解包含在JavaDoc中
public @interface FruitProvider {
public int id() default -1;
public String name() default "";
public String address() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GoodInfo {
public int id() default -1;
public String name() default "";
public String address() default "";
}
用上面两个注解标注类或类的成员变量
@GoodInfo(id=2, name="红富士", address="西安延安路")
public class Apple {
@FruitProvider(id=1, name="陕西红富士集团", address="陕西省西安市延安路")
private String appleProvider;
public String getAppleProvider() {
return appleProvider;
}
public void setAppleProvider(String appleProvider) {
this.appleProvider = appleProvider;
}
}
测试使用注解
Apple apple = new Apple();
Class<? extends Apple> clazz = apple.getClass();
// 类注解
GoodInfo info = clazz.getAnnotation(GoodInfo.class);
System.out.println("供应商编号:" + info.id() + ", 供应商名称:" + info.name() + ", 供应商地址:" + info.address());
// 成员变量注解
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
if (f.isAnnotationPresent(FruitProvider.class)) {
FruitProvider provider = f.getAnnotation(FruitProvider.class);
System.out.println(
"供应商编号:" + provider.id() + ", 供应商名称:" + provider.name() + ", 供应商地址:" + provider.address());
}
}