前言
自java5.0引入注解后,极大的改善了对于元数据的描述方式。注解为我们提供了可以在代码中添加信息,使我们在稍后某个时刻非常方便的使用这些数据。
在没有引入注解前,XML被广泛的用与描述元数据,但对于将元数据与代码分离的方式在某一些场合下维护变得越来越糟糕,他们希望使用一些和代码紧耦合的东西,而不是像XML那样和代码是松耦合的(在某些情况下甚至是完全分离的)代码描述,因此一种规范的耦合的描述元数据的方式Annotation便在后面产生了
注解分类
Java目前为我们提供了三种标准注解,以及四种元注解
- @Override,表示当前的方法定义覆盖超类中的方法,就是常用的继承后重写父类的方法,比如Android中常用的onCreate方法就使用了@Override
- @Deprecated,这个注解适用于类、方法、字段,当使用这个注解后,说明该方法或类不建议使用,在Android Studio中会有一个横线作为提示
- @Suppress Warnings,用于关闭不当的编译器警告信息
元注解的作用就是负责注解其他注解,Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解
- @Target 表示注解可以用于什么地方,可能的ElementType参数包括
参数 | 作用范围 |
---|---|
CONSTRUTOR | 构造器的声明 |
FIELD | 域声明(包括enum声明) |
LOCAL_VARIABLE | 局部变量声明 |
METHOD | 方法声明 |
PACKEGE | 包声明 |
PARAMETER | 参数声明 |
TYPE | 类、接口(包括注解类型)或enum声明 |
- @Retention表示需要在什么级别保存该注解信息,可选的RetentionPolicy参数包括
参数 | 保存级别 |
---|---|
SOURCE | 注解将被编译器丢弃 |
CLASS | 注解将在class中使用,但会被VM丢弃 |
RUNTIME | VM将在运行期也保存注解,因此可以根据反射获取到注解的信息 |
- @Documented :将注解包含着Javadoc中
- @Inherited :允许子类继承父类的注解
注解使用
注解的声明方式和接口很相似,只是在使用的时候是@interface,这里的注解是作用在方法上
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnnMethod {
String username() default "";
}
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnn {
String name() default "";
}
public class User {
@UserAnn(name = "张")
private String name;
@UserAnnMethod(username = "张珊")
public String getUserName() {
return "sss";
}
}
编写一个注解处理器
public class AnnotationUtils {
public static void getFruitInfo(Class<?> clazz) {
//获取属性
Field[] fields = clazz.getDeclaredFields();
//获取方法
Method[] methods = clazz.getDeclaredMethods();
for (Field f : fields) {
if (f.isAnnotationPresent(UserAnn.class)) {
UserAnn addre = f.getAnnotation(UserAnn.class);
System.out.print("属性注解:" + addre.name() + "\n");
}
}
for (Method med : methods) {
if (med.isAnnotationPresent(UserAnnMethod.class)) {
UserAnnMethod addre = med.getAnnotation(UserAnnMethod.class);
System.out.print("方法注解值:" + addre.username() + "\n");
}
String methodName = med.getName();
System.out.println("方法名称:" + methodName);
}
}
}
进行测试以及打印
public class AnnotationTest {
public static void main(String[] args) throws Exception {
AnnotationUtils.getFruitInfo(User.class);
}
}