java 注解的基本原理和编程实现

java 1.5开始引入了注解和反射,正确的来讲注解是反射的一部分,没有反射,注解没法正常使用,但离开注解,反射依旧可使用,所以来讲,php

反射的定义应该包含注解才合理一些。固然,这只是我的想法,至于java官方为何这么泾渭分明不得而知,最重要的是如何使用注解。java


注解的功能分为2部分:数组

  1. 做为特定的标记编辑器

  2. 额外信息的载体函数


>>>>定义一个UserAnnotation注解类spa

@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";
}

其中@target个@Retention自己就是注解插件

【@target】这个注解来指定给哪一类java成员注解,指定注解目标该是什么样的东西code

注解@Target的源码对象

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE) //这不是在做弊,这确实是本身注解本身,因此说注解也能够被字节给注解
public @interface Target {
    ElementType[] value(); //值可使数组 value={...}
}

public enum ElementType {
    TYPE,  //给类(型)注解
    FIELD, //给字段注解,不要忘了,字段能够是对象
    METHOD, //给方法注解
    PARAMETER, //给参数注解
    CONSTRUCTOR, //给构造方法注解
    LOCAL_VARIABLE, //给局部变量注解
    ANNOTATION_TYPE,//给注解注解(这貌似把本身不当类来看)
    PACKAGE, //给包注解
    TYPE_PARAMETER, //不知道,等知道了我再写在这里
    TYPE_USE //这个也不知道
}

【@Retention】表示注解运行的状态,换句话说,注解改在什么样的状态下才能运行接口

注解@Retention的源码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

public enum RetentionPolicy {
    SOURCE, //源码状态运行,
    CLASS, //编译类文件时运行
    RUNTIME //运行时运行
}

通常来讲,源码状态运行和编译状态运行的注解每每和编译器相关,好比报错,警告,类编译参数等,这2类状态通常和编辑器插件关系密切,这里再也不讨论

在平常开发中RUNTIME用的最多,这是开发人员能够控制的一个状态。


【@Documented】额,很少解释,具体来讲是生成说明文档时把类的解释添加进去


关于注解的方法说明,注解只有方法,没有字段,由于注解也是一个interface,只不过前面加了一个@符号,还有一点是这些方法没法实现,写法和C++的纯虚函数类似

请看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();
    objFiled.set(tm,new User(ua.age(),ua.gender(),ua.id(),ua.name())); //不错吧,将本身的信息送给obj,起到了附加信息的做用
    
    //-----------请自由遐想吧~~,下面来讲说注解怎么能得到注解本身的注解-------------
   Target t = ua.annotationType().getAnnotation(Target.class)
   ElementType[] values = t.value();
   //~~~~~~~~~~~~~~完了,再一次自由遐想吧~~~~~~~~~~~~~~
   
   Sysout.out.println("注意:是遐想,不是瞎想!!");
  }
}


try doing it.

相关文章
相关标签/搜索