文档章节

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

IamOkay
 IamOkay
发布于 2014/11/16 16:08
字数 962
阅读 11899
收藏 11

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

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


注解的功能分为2部分:

  1. 作为特定的标记

  2. 额外信息的载体


>>>>定义一个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";
}

其中@target个@Retention本身就是注解

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

注解@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.



© 著作权归作者所有

共有 人打赏支持
IamOkay
粉丝 187
博文 458
码字总数 370505
作品 0
海淀
程序员
加载中

评论(2)

花季童子
TestMain.class.getField("obj")
这里应该换成:TestMain.class.getDeclaredField("obj")
getField() 只能获取到private字段
KeepMoving
KeepMoving
例子不少错别字
Spring Boot实战之基础回顾

本文作者: 吴伟祥 本文链接: https://wuweixiang.cn/2018/08/21/Spring-Boot实战之基础回顾/ 版权声明: 本博客所有文章除特别声明外均为原创,采用CC BY-NC-SA 4.0 许可协议。转载请在文章开...

吴伟祥
昨天
0
0
IOC/AOP工具 - jBeanBox

jBeanBox是一个微形但功能较齐全的IOC/AOP工具适用于JAVA7+,利用了Java的初始化块实现的Java配置代替XML。jBeanBox采用Apache License 2.0开源协议。 其他一些IOC/AOP框架的问题: 1)Sprin...

yong9981
2016/07/25
0
14
详述三种现代JVM语言--Groovy,Scala和Clojure

Java的遗产将是平台,而不是程序设计语言。 Java技术的原始工程师们作出了一个明智的决定,就是将编程语言与运行时环境分开,最终这使得超过200种语言能够运行在Java平台上。这种架构对于该平...

Barudisshu
2014/07/31
0
0
Spring核心——JSR250与资源控制

JSR-175与元编程 要说明JSR-250先要解释清楚JSR-175,要解释清楚JSR就的先了解JCP是什么。网上资料很多,就不细说了,简单的说JCP(Java Community Process)是管理Java生态(包括J2SE、J2E...

随风溜达的向日葵
07/18
0
0
大数据开发培训:0基础学习Java编程语言有哪些知识点?

Java 技术通用、高效、具有平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网等,学习Java首先要知道学习知识点有哪些。在这就用加米谷大数据培训...

加米谷大数据
07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
38分钟前
3
0
invalid character found in the request target 异常

这个异常时因为Tomcat 9不支持请求格式出现“{”等非法字符的问题 因为tomcat版本问题遇到的坑,记录一下。 问题 今天由于要测试一下订单详情页的异步查询,在本地起了一个服务,发送的请求是...

edwardGe
42分钟前
4
0
发现抓包软件fiddler的bug

1个请求他跳转之后,直接400,被拦在了Apache,使用fiddler 的,replay requests 是同样的结果,但是replay composer确是正常的。 也就是说这replay requests 是发原来的包,replay composer...

NLGBZJ
52分钟前
1
0
linux screen 命令详解

shell关闭后, 主机仍然运行 screen命令 启动jenkins以后, screen, 然后按ctrl+a 再按d 这样暂停了子界面, 这时候回到了父界面 用screen –ls查看目前子界面的状态 [root@free /]# screen -l...

SuShine
53分钟前
4
0
mac机器切换无线网络导致网页不能打开的问题

问题: 公司和家里使用不同的WI-FI,每次从家到公司时自动切换网络后,公司的许多地址不能访问, ping域名是可以ping同的,但是网页却打不开... 问题分析: 初步猜想是DNS缓存的问题? 对于MAC系统没...

Lennie002
56分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部