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

网友投稿 303 2023-04-27


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

注解是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表明该注解在使用javadohttp://c工具生成开发文档时,也会被纳入进去.

@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(XNYUlI) 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通过动态代理技术生成的.这也揭示了注解特性的底层实现原理.关于注解的具体底层技术原理,这里不再详谈.


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:URLConnection发送HTTP请求的方法_动力节点Java学院整理
下一篇:基于bootstrap实现多个下拉框同时搜索功能
相关文章

 发表评论

暂时没有评论,来抢沙发吧~