java annotation详解

摘要

java annotation是jdk1.5引入的一种注解机制,记录一下注解的官方含义注解的定义

Annotations,a form of metadata,provide data about a program that is not part of the program
itself.Annotations have no direct effect on the operation of code they annotate

介绍中有一个关键词metadata,我们理解为元数据,那元数据我们怎么理解呢,其实就是描述数据的数据,java中以对象为基本,描述一个事物我们都喜欢把其抽象为一个对象,但是我们用什么样的数据去描述对象呢,因为对象本身也是一个数据,我倾向于把注解比喻为一个商品的标签,标签上可能记录的是该商品的元数据,比如价格,货号等,但是提供的信息却不是这个商品本身,就算把标签拿去也是不影响这个商品的使用。这样理解也是契合了官方介绍下的定义,就像反射的含义一样,把java类中的各种成分映射成响应的类,注解其实也是对于java类中的各个成分的一个标签。

常见的注解

@ Override
public String toString(){
      return "this is String";
}

我们平时的代码编写中,@Override注解随处可见,可以尝试一些就算我把toString方法上的注解删除掉,代码也是可以运行的没有任何的问题,那思考一下那这个注解有什么用呢?我们上面把注解理解为商标,其实这个注解就是告诉编译器,这是一个方法,什么样的方法呢,是一个加了标签的方法,什么标签呢,一个加了重写标签的代码,并且编译器还可以发出错误,当他父类没有这个方法的时候,当可能我手滑了,toString写成toSString(),如果我没有加这个注解,其实是一帆风顺的,但是后面得到的情况就和我想要的不一样了。

为什么要引入注解

了解了一下jdk为何需要引入注解的历史,在注解以前,xml这种数据结构可能被广泛应用与元数据的描述,但是在某个特定的时期,一些开发人员觉得xml维护很麻烦,他们需要一种可以和代码更加密切的东西而不是xml有时可能和代码完全分开,有兴趣可以google一下xml vs annntations,但是注解就一定会比xml更好吗?其实也需要分场景,对于项目中的一些环境变量和参数,其实可以使用xml,可以和代码完成的区分开,但是如果你想修饰一些方法,类可能注解是更好的选择,所以我想这也是spring支持注解+xml两种方式的原因吧。

java中的注解组成

java annotation组成

  • Annotation.java
public interface Annotation {
       boolean equals(Object obj);
        int hashCode();
        String toString();
         Class<? extends Annotation> annotationType();
}
  • ElementType.java
package java.lang.annotation;

public enum ElementType {
    TYPE,               /* 类、接口(包括注释类型)或枚举声明  */
    FIELD,              /* 字段声明(包括枚举常量)  */
    METHOD,             /* 方法声明  */
    PARAMETER,          /* 参数声明  */
    CONSTRUCTOR,        /* 构造方法声明  */
    LOCAL_VARIABLE,     /* 局部变量声明  */
    ANNOTATION_TYPE,    /* 注释类型声明  */
    PACKAGE             /* 包声明  */
}
  • RetentionPolicy.java
public enum RetentionPolicy {
    SOURCE,           
    CLASS,             
    RUNTIME            
}

说明:
(01)、我们可以把RetentionPolicy理解为有效的时间,我们可以查一下定义,分析一下这个枚举的三个元素的意思:
1、SOURCE:表明此种类型的注解仅存在与编译期间,编译完成以后这个注解就没有用了,根本都到不了字节码这个级别,比如我们常见的@Override,其实也就是在编译的时候判断该注解标记的方法是否父类有这个方法。
2、CLASS:仅存在类加载期间,类加载完成这个注解就没什么用了,这是一个默认值
3、RUNTIME:不会存在没用的情况,直接会将Annotation存储在class文件中,并且可由JVM读入,也是我们定义自定义注解选择的方式。
所以对于这三个关键组成,一个注解必须绑定一个RetentionPolicy和多个ElementType。

java提供的注解(以下4个注解只能标注在Annotaion类型上,也就是这四个注解只能标注注解)

  • @Documented 所标注的内容,会出现在javadoc中

  • @Retention 该注解是标注注解的RetentionPolicy

  • @Target 该注解是标注注解的ElementType

  • @Inherited 它所标记的注解具有继承的属性

  • @Override 只能标示在方法上,表明该方法是其父类方法的重写

  • @ Deprecated 所标注的内容,表明不被建议使用

  • @ SuppressWarnings 所标注的内容产生的警告,编译器可以忽略

  • @interface 定义一个Annotation类型,但是注意的是和interface是不同的,被标记以后,该注解就不能继承其他的注解或接口了。

注解的使用场景

1、编译检查

自定义注解
IDE提示.png

如图所示,重写toString()方法但是没有添加@Override注解,IDE会提醒。
2、在反射中使用Annotation
如果我们使用过java的反射代码,我们可以在代码中看到反射提供的类,方法和属性字段都有一个共同的方法getAnnotation()来返回注解对象。

使用demo
Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(" Method Name : " + method.getName());
System.out.println(" Author : " + todoAnnotation.author());
System.out.println(" Priority : " + todoAnnotation.priority());
System.out.println(" Status : " + todoAnnotation.status());
}
}

3、使用Annotation生成文档
使用@Documented会生成文档。
4、帮助查询代码
通过部分注解我们可以知道更容易知道方法之间的关系。

自定义注解

但是我们在一些开源框架中会经常看到一些框架中自定义的注解,比如我们常用的spring框架等,@Controller,@RequestMapping等,我们可以根据java原生的注解实现我们自定义的注解。

//实现用户的自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface ToDO {
    public enum level{LOW,MEDIUM,High}
    public enum state{stared,finished}
    String author() default "pjw";
    level level() default level.LOW;
    state state() default state.stared;
}

 @ToDO(level = ToDO.level.MEDIUM,author = "pjq",state = ToDO.state.finished)
    public static String getString(){
        return "";
    }

总结

其实我们可以把注解理解成一个特殊的java类,其实我们会发现注解可以干的事情配置文件也是可以干的,在实际我们的编程中,其实注解和配置文件是携同工作的,只是使用场景哪一种更为合适,仅此而已。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351