注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
在开发过程中,我们见到的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
:
@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
,如下:
从上面的元注解部分我们可以知道,我们定义的注解MyAnnotation
只能用于注解包,而不能用于注解方法、域等。
参数: 从前面的@SuppressWarnings
中我们可以知道,注解还可以带参数,不过在注解中的参数类型有点奇怪,如下:
默认情况下,如果只有一个参数类型,我们将变量命名为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竹子,在此对竹子表示感谢。如果本文涉及的一些内容有一些版权争议,还请与我联系。
新闻热点
疑难解答