详解Java注解( Annotation )

详解Java注解( Annotation )

注解的定义:

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释

注解的作用

  • 生成文档

  • 代码分析,通过代码里的元数据来对代码进行分析

  • 在编译的时候进行检查

JDK自带的注解

在开发过程中,我们见到的JDK自带的注解主要有三个,分别是@Override@SuppressWarnings@Deprecated,作用分别如下:

  • @Override

  • 主要用于标识所用的方法是继承自父类的方法,从而在编译的过程中可以被编译器检测到,如果某个方法使用了该注解,但是方法的签名(方法名以及参数类型)与父类不一致,则在编译的过程中,编译器会抛出错误,用于提示开发者。

  • 最常见的就是toString()方法了,该方法继承自Object类。如果我们在重写该方法的时候,没有使用该注解,然后不小心将该方法的名字写错如下所示:


package cn.xuhuanfeng.annotation;

public class TestAnnotation {

public static void main(String[] args) {

TestAnnotation test = new TestAnnotation();

System.out.println(test.toString());

}

public String tostring() {

return "Not true";

}

}

输出结果为:cn.xuhuanfeng.annotation.TestAnnotation@15db9742,显然我们可以看到,toString()方法输出的结果显然不是我们所期待的,有时候就会很莫名其妙了(原因是重写toString() 方法的时候,不小心将S写错成了s,编译器会理解成有一个新的方法,叫tostring(),这是正确的,所以就导致了调用的时候出现了预期之外的结果了),但是如果我们在重写toString()方法的时候,加上@Override,这个时候,如果还是按照上面的写法,编译器就会告诉我们The method tostring() of type TestAnnotation must override or implement a supertype method,于是,我们很容易就能发现问题所在了,这是注解的好处之一,也是@Override 的作用,具体可以查看其源码即可。

  • @Deprecated

  • 主要用于标识该包、方法、域、变量等已经不推荐使用了,一旦标识了该注解,则对应的方法、域等会划上删除线如下所示


@Deprecated

public void test(){

System.out.println("Deprecated");

}

  • @SuppressWarnings

  • 主要用于压制编译器发出的警告,该注解需要提供参数,包括了unchecked all 等,分别对应不同的压制范围,如:


@SuppressWarnings("all")

public void test01(){

}

自定义注解

上面我们看到了JDK中自带的注解,虽然很有用,但是毕竟范围有限,种类也有限,实用性不是很大,于是Java开发者为我们提供了自定义的注解,极大了扩展了该功能,下面我们就详细来看下自定义注解的内容。

元注解

为了使用自定义注解,首先我们需要了解一个概念:元注解,所谓的元注解,其实就是注解的注解,也就是用来表示注解的注解,JDK中包含的元注解中比较常用的有以下几种类型: @Target , @Retention , @Documented , @Inherited ,其中前面两种在实际开发过程中用得比较多,所以下面我们着重来介绍这两种:

  • @Target :

  • 用于表示所标识的注解的使用范围,其值可以是 ElementType.PACKAGE , ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD 等,分别对应的标识对象为 包,构造器,方法,域变量,也就是说,只有包含了该范围,我们定义出来的注解才能用于对应的域,多种类型可以组合使用,只需要使用{}包括起即可。

  • 具体使用如下:

@Target({ElementType.PACKAGE,ElementType.CONSTRUCTOR ,ElementType.METHOD, ElementType.FIELD})

  • @Retention

  • 用于标识注解的存活周期,包括了RetentionPolicy.RUNTIME,RetentionPolicy.CLASS,RetentionPolicy.SOURCE,分别对应存活周期为运行时,字节码,源文件。

  • 运行时:标识该注解存在于字节码中,并且在运行过程中会被JVM加载,可用于反射操作。

  • 字节码:标识该注解存在于字节码中,但是运行时不被JVM加载,默认的形式。

  • 源文件:标识该注解只存在源文件中,在编译过程会被编译器丢弃。

  • 具体使用如下:


@Retention(RetentionPolicy.RUNTIME)

自定义注解

学习完了元注解之后,我们就可以开始手动编写自定义的注解了。

  • 格式:

自定义注解的书写方式跟普通的Java类的书写方式接近,只是将class 关键字替换为@interface ,如下:


@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.PACKAGE})

public @interface MyAnnotation {

}

从上面的元注解部分我们可以知道,我们定义的注解MyAnnotation 只能用于注解包,而不能用于注解方法、域等。

  • 参数:

从前面的@SuppressWarnings 中我们可以知道,注解还可以带参数,不过在注解中的参数类型有点奇怪,如下:


String value();// String为参数类型 value() 整体为变量

String[] value(); // String[] 为参数类型 value() 整体为变量

默认情况下,如果只有一个参数类型,我们将变量命名为value(),我们也可以声明多个参数


String name();

int age(); // 其他类型依此类推

在注解中的所有参数均可以指定默认的值,如下:


String name() default "";

int age() default -1;

由于在使用注解中我们无法标识错误的情况,所以一般情况下,会将默认类型指定为一个不合理值,用来处理注解时判断所使用的值是合理还是不合理。

  • 使用:

定义完了一个我们的自定义注解之后,接下来我们来看下如何使用它。使用的方式跟JDK自带的注解的方式基本一致,指定对应的键值对,key为定义的参数名字,值为需要传入的值,如果是数组类型,则传入数组即可。


@MyAnnotation(name="xuhaunfeng",age=23)

public void test(){}

//在MyAnnotation中多增加一个变量为 String[] parents();

@MyAnnotation(name="xuhaunfeng",age=23,parents={"AA","BB"})

public void test(){}

注解的应用

看完了上面的内容,可能你会觉得如果注解只是上面的用法,感觉上是没有任何作用的,确实,上面所介绍的内容都是注解的格式、定义等,但是没有涉及到其应用,注解配合反射,可以实现很多功能,例如:ORM的实现,框架中Annotation的应用等,不过目前我还没有学习到这些内容,所以在后期学习之后将会补上,敬请期待。

参考说明

这篇文章只是我个人学习过程中的一些笔记,不带有任何的商业目的,在学习过程中参考了很多的资料,主要参考深入理解Java:注解(Annotation)自定义注解入门 By竹子,在此对竹子表示感谢。如果本文涉及的一些内容有一些版权争议,还请与我联系。

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

推荐阅读更多精彩内容