当前位置: 移动技术网 > IT编程>开发语言>Java > 深入理解Java注解的使用方法

深入理解Java注解的使用方法

2019年07月22日  | 移动技术网IT编程  | 我要评论

注解是jdk1.5新增的特性.大家都知道,jdk1.5在java的发展史上有着划时代的意义.而注解的出现,在某种程度上颠覆了框架的设计.比如,spring在注解出现后,改善了原先五大组件的模式,增加了基于注解的实现方式.现在重点讲讲注解的使用.

元注解:

      jdk1.5定义了4个元注解,元注解的作用是注解其他的注解.

       1.@retention

       2.@target

       3.@documented

       4.@inherited

       @retention用于指明该注解存在的时机.参数有三个值可选:retentionpolicy.source,retentionpolicy.class,retentionpolicy.runtime可供选择.分别表示:源码中保留注解,字节码文件中保留注解,运行时保留注解.

       @target用于指明注解能作用的范围.比如参数中设置为elementtype.type,表示作用于类和接口.如果你用来注解方法,则会发生编译错误.由此可见它的功能是通过编译器实现的.

       @documented表明该注解在使用javadoc工具生成开发文档时,也会被纳入进去.

       @inherited表明,某个位置使用该注解,那么在存在java继承关系的地方,该注解也能被继承过来.这个可能不好理解.下面的代码加以说明.     

@retention(retentionpolicy.runtime)
@target({elementtype.type,elementtype.method})
@inherited
public @interface annoinherited {
  
}


测试代码:

public class testannoinherated {
  public static void main(string[] args) {
    annotation[] annos=new goo().getclass().getannotations();
    for(annotation a:annos){
      system.out.println(a);
    }
  }
}

@annoinherited
class foo{
  
}

class goo extends foo{
  
}  

控制台输出:

@test.annotation.annoinherited()

上例中goo前面并没有加注解@annoinherited,但是父类foo前面有,而@annoinherited加了元注解@inherited,所以foo能继承过来.

自定义注解:

自定义注解的实例如下.

package test.annotation;

import java.lang.annotation.documented;
import java.lang.annotation.elementtype;
import java.lang.annotation.retention;
import java.lang.annotation.retentionpolicy;
import java.lang.annotation.target;

@target(elementtype.type)
@retention(retentionpolicy.runtime)
@documented
public @interface animalinfo {
  string shout() default "";
  
  //能不能看门
  boolean isguard() default true;
}

测试代码:

public class testanimalinfo {
  public static void main(string[] args) {
    animal animal=new animal();
    animalinfo info=animal.getclass().getannotation(animalinfo.class);
    if(info!=null){
      annotation anno=info;//此处并没有报错.annotation是一个接口.info是一个注解.这是因为编译器会将注解编译成接口,并且继承了annotation
      system.out.println("annotation类信息:"+annotation.class);
      system.out.println("animalinfo类信息:"+animalinfo.class);
      class[] cs=animalinfo.class.getinterfaces();
      for(class c:cs){
        system.out.println(c); //animalinfo编译后就是一个接口,并且继承了annotation,这里得到了证实.
      }
      system.out.println("info对象的类信息:"+info.getclass());
      if("wangwang".equals(info.shout())&&info.isguard()){
        system.out.println("the animal is a dog");
      }else if("miaomiao".equals(info.shout())&&!info.isguard()){
        system.out.println("the animal is a cat");
      }else{
        system.out.println("the animal is not a dog or cat");
      }
    }else{
      system.out.println("it's not a animal");
    }
  }
}

@animalinfo(shout="wangwang",isguard=true)
class animal{
  
}

控制台输出:

annotation类信息:interface java.lang.annotation.annotation
animalinfo类信息:interface test.annotation.animalinfo
interface java.lang.annotation.annotation
info对象的类信息:class com.sun.proxy.$proxy1
the animal is a dog

代码分析:从控制台可以看到.@animalinfo注解其实编译后就是接口,并且它继承了annnotation.而通过反射获得的注解实例,名字为$proxy1,是一个类的对象.可见,该注解实例是jvm通过动态代理技术生成的.这也揭示了注解特性的底层实现原理.关于注解的具体底层技术原理,这里不再详谈.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网