Java自定义注解的简单使用,亲手撸一个和 @Valuse 功能一样的注解。
使用自定义注解之前先要了解元注解 ,解释如下:
元注解的作用就是负责注解其他注解,java 5.0定义了4个meta-annotation类型,用来提供对爱他的annotation类型做说明。
- @Target
- @Retention
- @Document
- @Inhrited
接下来进行介绍加举例
@Target
修饰的对象范围:packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。
描述注解的使用范围。
ElementType取值:
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
例如自定义注解类成员变量:
@Target(ElementType.FIELD)
@Documented
public @interface Name {
String value() default "";
}
自定义注解类:
@Target(ElementType.TYPE)
public @interface Person {
String value() default "";
@Retention
表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
RetentionPoicy取值:
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在运行时有效(即运行时保留)
例如 Name 注解的 RetentionPolicy 的值为 RUNTIME ,这样注解处理器可以通过反射,获取到该注解的属性,从而做一些运行时的逻辑处理。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
String value() default "";
}
@Document
用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
String value() default "";
@Inhrited
@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了 @Inherited 修饰的 annotation 类型被用于一个 class,则这个 annotation 将被用于该 class 的子类。
自定义注解
格式:
public @interface 注解名{
}
成员类型:
- 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型
- 以上所有类型的数组
注意:
- 只能用 public 或者 default 修饰,如 String name();
- 只有一个变量时最好使用 value() ,例如 String value();
举个自定义注解,并赋值的简单例子:
自定义注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MySource {
String value() default "mgg";
}
Person 类,注入属性。
public class Person {
@MySource("kangkang")
public String name;
@MySource("男")
public String gender;
}
测试类,使用反射在运行时给对象属性赋值:
public class Test {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
// TODO Auto-generated method stub
Person p = new Person();
setvalue(p);
System.out.println(p.name);
System.out.println(p.gender);
}
public static void setvalue(Object o) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = o.getClass().getDeclaredFields();
for (Field f : fields) {
MySource ms = f.getAnnotation(MySource.class);
if (ms != null) {
f.set(o, ms.value().toString());
}
}
}
}
运行成功了吗,是不是很简单?如你所见,我们自定义的注解通过 Java 反射机制在运行时做相应的逻辑处理,Java 的注解就是基于 反射机制,而且学习 Java 越深入越能体会反射机制的牛批之处。