注解:是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用。
>>>>定义一个UserAnnotation注解类
@Target(value = {ElementType.FIELD}) //表示注解被使用在字段上
@Retention(RetentionPolicy.RUNTIME) //表示注解在运行时生效
public @interface UserAnnotation {
public int id() default 0;
public String name() default "";
public int age() default 18;
public String gender() default "M";
}
public enum ElementType {
TYPE, //给类(型)注解
FIELD, //给字段注解,不要忘了,字段可以是对象
METHOD, //给方法注解
PARAMETER, //给参数注解
CONSTRUCTOR, //给构造方法注解
LOCAL_VARIABLE, //给局部变量注解
ANNOTATION_TYPE, //给注解注解(这貌似把自己不当类来看)
PACKAGE, //给包注解
TYPE_PARAMETER, //不知道,等知道了我再写在这里
TYPE_USE //这个也不知道
}
【@target】用于定义注解可以在哪些地方使用
【@Retention】表示注解运行的状态,换句话说,注解改在什么样的状态下才能运行
注解@Retention的源码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
public enum RetentionPolicy {
SOURCE, //源码状态运行
CLASS, //编译类文件时运行
RUNTIME //运行时运行
}
通常使用中,@target、@retention是必选项。
ElementType根据需要,来指定该注解用在哪些地方(类/字段、方法、参数).
RetentionPolicy通常使用RUNTIME,在日常开发中RUNTIME用的最多。
关于注解的方法说明,注解只有方法,没有字段,因为注解也是一个interface,只不过前面加了一个@符号。
请看id()方法的解释
public int id() default 0;
/*首先,方法必须是public的,去掉public,默认也是public,接口interface不也是这样么
*其次,default默认值不是必须的,方法必须有返回值,返回值可以是java中复杂对象,也可以是基本类型,枚举都行
*如 ElementType[] value();
*/
注解定义好了,怎么使用呢,如下:
public class TestMain {
@UserAnnotation(age=20, gender="F", id=2014, name="zhangsan") //注解的使用
private Object obj;
public static void main(String[] args) throws Exception {
Filed objField = TestMain.class.getField("obj");
//得到注解,起到了标记的作用
UserAnnotation ua = objField.getAnnotation(UserAnnotation.class);
System.out.println(ua.age()+","+ua.gender()+","+ua.id()+","+ua.name());
//***进一步操作的话,假设Object要指向一个User类,那么可以讲注解的值给他
TestMain tm = new TestMain();
//不错吧,将自己的信息送给obj,起到了附加信息的作用
objFiled.set(tm,new User(ua.age(), ua.gender(), ua.id(), ua.name()));
//-----------请自由遐想吧~~,下面来说说注解怎么能获得注解自己的注解-------------
Target t = ua.annotationType().getAnnotation(Target.class)
ElementType[] values = t.value();
//~~~~~~~~~~~~~~完了,再一次自由遐想吧~~~~~~~~~~~~~~
Sysout.out.println("注意:是遐想,不是瞎想!!");
}
}