注解的基本概念
注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
定义注解的方式
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
}
如上面代码中看到的,一个简单的自定义注解就这样诞生了。有的同学可能会奇怪,为什么需要有@Target,@Retention这两个注解来修饰我们自定义的注解@Test呢?原来当我们在定义注解时,需要用元注解来对我们的注解进行一定的说明。@Target用来定义你的注解将应用于什么地方(例如是一个方法或者一个域)。@Retention用来定义该注解在哪一个级别可用,在源代码中(SOURCE),在类文件中(ClASS)或者在运行时(RUNTIME)。
元注解
上面我们在自定义注解时,发现我们需要元注解来帮忙,那元注解到底有哪些呢?他们分别起的作用有事什么呢?让我们来一起看一下。
元注解 | 说明 |
---|---|
@Target | 表示该注解可以用于什么地方。可能的ElementType参数包括:CONSTRUCTOR:构造器的声明。 FIELD:域声明(包括enum实例)。LOCAL_VARIABLE:局部变量声明。METHOD:方法声明。PACKAGE:包声明。PARAMETER:参数声明。TYPE:类,接口(包括注解类)或enum声明。 |
@Retention | 表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:SOURCE:注解将被编译器丢弃。CLASS:注解在class文件中可用,但会被VM丢弃。RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息。 |
@Documented | 将此注解包含在javadoc中。 |
@Inherited | 允许子类继承父类中的注解。 |
注解元素
在注解中我们是可以自定义元素的。但是是不是所有的类型都可以作为注解的元素呢?下面我们一起来看一下Java中对注解元素的规定。
- 所有基本类型(int,float,boolean,double,long等)
- String
- Class
- enum
- Annotation
- 以上类型的数组
这里需要强调一下的是:不允许使用任何包装类型
默认值限制
在给我们自己定义的注解添加注解元素的时候,我们是可以给这些注解元素添加默认值的,这里对默认值有有一些要求,主要是一下两点:
- 元素不能有不确定的值。也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值。
- 对于非基本类型的元素,无论在源代码中声明时,或是在注解接口中定义默认值时,都不能以null为其值。
动手试一试
写了这么多概念性的东西,感觉是时候动手写一下了。
首先我们自定义一个注解,
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationTest{
public String name() default "";
public int code() default 0;
public Class clazz() Object.class;
}
然后我们定义一个实体类
public class AnnotationModel{
@AnnotationTest(name="时间",code=1,clazz=Date.class)
public Date startDate;
public Date getStartDate(){
return startDate;
}
public void setStartDate(Date date) {
this.startDate = date;
}
}
最后,我们通过反射的方法获取到定义到FIELD中的注解信息。
public class AnnotationMain{
public static void main(String[] args) {
Class<?> modelClazz = AnnotationModel.class;
Field[] fields = modelClazz.getDeclaredFields();
for(Field field : fields) {
// 获取指定的注解
AnnotationTest annotationTest = field.getAnnotation(AnnotationTest.class);
if(null == annotationTest) {
continue;
}
System.out.println(annotationTest.name);
System.out.println(annotationTest.code);
System.out.println(annotationTest.clazz);
}
}
}
写到这里就差不多了,后面还有嵌套注解,感兴趣的同学可以自己尝试一下。
网友评论