JDK5.0 Annotation学习笔记(一)
背景知识:
从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范。注释是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked")。注释可以附加在package, class, method,
field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。如果没有外部解析工具等对其加以解析和处理的情况,本身不会对Java的源代码或class文件等产生任何影响,也不会对它们的执行产生任何影响。
元数据的作用,大致可分为三种:编写文档,通过代码里标识的元数据生成文档;代码分析,通过代码里标识的元数据对代码进行分析;编译检查,通过代码里标识的元数据让编译器能实现基本的编译检查。
JDK5内置的基本注释
JDK5内置了一些常用的注释,可以在编译时帮我们捕获部分编译错误,及提示信息,下面介绍下这些注释的用法:
1、@Override定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;代码如下:
- public class OverrideDemo {
- @Override
- public String tostring() {
- return super.toString();
- }
- }
在编译时,会提示以下错误信息:
@Override
^1 错误
2、@Deprecated定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。使用@Deprecated的示例代码如下:
- public class DeprecatedDemo {
- public static void main(String[] args) {
- DeprecatedClass.DeprecatedMethod();
- }
- }
- class DeprecatedClass {
- @Deprecated
- public static void DeprecatedMethod() {
- // TODO
- }
- }
在编译时,会得到以下提示信息:
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
如果在编译时添加-Xlint:deprecation参数,我们能更清楚的看到该警告的详细信息,如下:
SomeClass.DeprecatedMethod();
^1 警告
要注意@Deprecated与@deprecated的区别,@deprecated是为了生成文档的需要,例如:
- class DeprecatedClass {
- /**
- * @deprecated 此方法已过时,不建议使用
- */
- @Deprecated
- public static void DeprecatedMethod() {
- // TODO
- }
- }
3、@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数unchecked为例,为你展示如何使用@SuppressWarnings注释,示例代码如下:
- import java.util.List;
- import java.util.ArrayList;
- public class SuppressWarningsDemo {
- public static List cache = new ArrayList();
- //@SuppressWarnings(value = "unchecked")
- public void add(String data) {
- cache.add(data);
- }
- }
当我们不使用@SuppressWarnings注释时,编译器就会有如下提示:
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
下面我们去掉@SuppressWarnings(value="unchecked")这一行的注释符“//”,它会屏蔽编译时的警告信息,这也就是它所要达到的目的。
另外,由于@SuppressWarnings注释只有一个参数,并且参数名为value,所以我们可以将上面一句注释简写为
@SuppressWarnings("unchecked");
同时参数value可以取多个值如:
@SuppressWarnings(value={"unchecked", "deprecation"})
或@SuppressWarnings({"unchecked", "deprecation"})。
自定义Annotation注释
1、注释annotation与接口的异同:
因为annotation类型是一个非凡的接口,所以它与接口之间存在着某些差异:
A. Annotation类型使用关键字@interface而不是interface,这个关键字声明隐含了一个信息,它是继承了java.lang.annotation.Annotation接口,并非声明了一个interface。
B. Annotation类型的方法定义是独特的、受限制的,方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了成员名,而方法返回值成为了成员的类型。而方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组。方法的后面可以使用default和一个默认数值来声明成员的默认值,null不能作为成员默认值,这与我们在非annotation类型中定义方法有很大不同。
C. Annotation类型又与接口有着近似之处,它们可以定义常量、静态成员类型(比如枚举类型定义)。Annotation类型也可以如接口一般被实现或者继承。
2、自定义注释的实例:
下面,我们将看到如何定义annotation类型的例子。它展示了annotation类型声明以及
- @interface与interface之间的不同:
- import java.lang.annotation.*;
- /**
- * 使用annotation来描述那些被标注的成员是不稳定的,需要更改
- */
- public @interface Unstable {
- }
下面的另一个例子只定义了一个成员。并通过将这个成员命名为value,使我们可以方便的使用这种annotation的快捷声明方式:
- /**
- * 使用Author这个annotation定义在程序中指出代码的作者
- */
- public @interface Author {
- /** 返回作者名 */
- String value();
- }
以下的例子更加复杂。Reviews annotation类型只有一个成员,但是这个成员的类型是复杂的:由Review annotation组成的数组。Review annotation类型有3个成员:枚举类型成员grade、表示Review名称的字符串类型成员Reviewer、具有默认值的字符串类型成员
Comment。
- /**
- * Reviews annotation类型只有一个成员,
- * 但是这个成员的类型是复杂的:由Review annotation组成的数组
- */
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Reviews {
- Review[] value();
- }
- /**
- * Review annotation类型有3个成员:
- * 枚举类型成员grade、
- * 表示Review名称的字符串类型成员Reviewer、
- * 具有默认值的字符串类型成员Comment。
- */
- public @interface Review {
- // 内嵌的枚举类型
- public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };
- // 下面的方法定义了annotation的成员
- Grade grade();
- String reviewer();
- String comment() default "";
- }
最后,我们来定义一个annotation方法用于罗列出类运行中所有的unchecked异常。这个 annotation类型将一个数组作为了唯一的成员。数组中的每个元素都是异常类。为了加强对未检查的异常(此类异常都是在运行时抛出)进行报告,我们可以在代码中对异常的类型进行限制:
- public @interface UncheckedExceptions {
- Class[] value();
- }
Meta-Annotation类型:
Annotation 类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,分别是:Target、Retention、Documented、Inherited,它们被用来提供对其它annotation类型作说明。 这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target的用法:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在
Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,以下这个注释只能用来声明方法:
- @Target(ElementType.METHOD)
- public @interface MyAnnotation {
- ...
- }
java.lang.annotation.ElementType是一个枚举类型,它具有以下定义:
@Retention的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在
Retention 注释,则保留策略默认为 RetentionPolicy.CLASS,例如:
- @ Retention(RetentionPolicy.CLASS)
- public @interface MyAnnotation {
- ...
- }
java.lang.annotation.RetentionPolicy是一个枚举类型,它具有以下定义:
@Documented的用法:指示某一类型的注释将通过 javadoc
和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。Documented是一个没有成员的注释。
@Inherited的用法:指示注释类型自动被子类继承。 Inherited也是一个没有成员的注释。
注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。
JDK5.0 Annotation学习笔记(一)的更多相关文章
- 从零开始搭建.NET Core 2.0 API(学习笔记一)
从零开始搭建.NET Core 2.0 API(学习笔记一) 一. VS 2017 新建一个项目 选择ASP.NET Core Web应用程序,再选择Web API,选择ASP.NET Core 2. ...
- Swift 2.0 字符串学习笔记(建议掌握OC字符串知识的翻阅)
自己公司开现在使用OC语言在写,但Swift似乎是苹果更推荐使用的开发语言,估计也是未来开发的趋势,自己以前有接触swift,但又由于公司的项目赶,也没有时间去好好地学习这款开发语言.现在年底了,项目 ...
- Spring 4.0.2 学习笔记(2) - 自动注入及properties文件的使用
接上一篇继续, 学习了基本的注入使用后,可能有人会跟我一样觉得有点不爽,Programmer的每个Field,至少要有一个setter,这样spring配置文件中才能用<property> ...
- Spring3的IOC的annotation学习笔记
以下记录了一个小小的Spring3的annotation的应用笔记. 文件列表: UserService-interface UserDao-interface UserServiceImpl-Use ...
- Spring 4.0.2 学习笔记(1) - 最基本的注入
1. 添加maven支持 <dependency> <groupId>org.springframework</groupId> <artifactId> ...
- Google Guava14.0 瓜娃学习笔记
Guava 是java api的增强与扩展,提供复杂的java 数据结构,使你的代码更简短精炼,具有良好的可读性.看看guava给我们提供了哪些很酷的功能: 集合创建: Map<String, ...
- 《Ruby语言入门教程v1.0》学习笔记-01
<Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...
- Swift2.0 函数学习笔记
最近又有点忙,忙着找工作,忙着适应这个新环境.现在好了,上班两周周了,也适应过来了,又有时间安安静静的就行我们前面的学习了.今天这篇笔记,记录的就是函数的使用.下面这些代码基本上是理清楚了函数的额使用 ...
- Vue1.0基础学习笔记整理
最近一直在使用Vue.js开发项目,现将在学习过程中遇到的一些学习小细节总结如下: 1.只处理单次插值,今后的数据变化就不会再引起插值更新了 <span>This will never c ...
随机推荐
- 使用svn时出现Can't switch /XXX/XXX because it is not the repository yet
问题描述 出现的问题如题目所示. 翻译一下:不能选择这个目录,原因是这个目录还不是svn仓库. 解决办法 这个问题出现的原因是你将项目中的.svn文件夹删除了,一般情况你是可以通过撤销将文件恢复的.如 ...
- 线上环境 分析java问题 常见命令
在生产上进程需要分析jvm运行情况,今天分享几个自己常用的命令,持续更新,欢迎补充 1.jps jstack -l {pid} > jstack.log #查看线程快照信息 2.jps jmap ...
- java多线程之volatile关键字
public class ThreadVolatile extends Thread { public boolean flag=true; @Override public void run() { ...
- OpenStack(四)——使用Kolla部署OpenStack多节点云
(1).实验环境 主机名 IP地址 角色 内存 网卡 CPU 磁盘 OpenStack-con 192.168.128.110 controller(控制) 8G 桥接网卡ens32和ens33 4核 ...
- BZOJ [HAOI2006]旅行comf
题解:枚举最大边,然后对<=最大边的边做最大生成树,使最小边最大 #include<iostream> #include<cstdio> #include<cstr ...
- codeigniter框架开发技巧
codeigniter框架开发技巧 来源:未知 时间:2014-10-20 11:36 阅读数:171 作者:xbdadmin [导读] (1)自动加载modelsphp5风格 使用这个 ...
- UVA 11987 - Almost Union-Find 并查集的活用 id化查找
受教了,感谢玉斌大神的博客. 这道题最难的地方就是操作2,将一个集合中的一个点单独移到另一个集合,因为并查集的性质,如果该点本身作为root节点的话,怎么保证其他点不受影响. 玉斌大神的思路很厉害,受 ...
- 1-4 无监督学习(Unsupervised Learning)
无监督学习定义: [无监督学习]中没有任何的标签或者是有相同的标签或者就是没标签.所以我们已知数据集,却不知如何处理,也未告知每个数据点是什么.别的都不知道,就是一个数据集.你能从数据中找到某种结构吗 ...
- scrapy 在pycharm中调试 不用到命令行中启动爬虫方法
(目录结构如上图) 在主目录中加入main.py,在其中加入代码,运行此文件就可以运行整个爬虫: # -*- coding: utf-8 -*- __author__='pasaulis' #在程序中 ...
- socket实践编程1
1.服务器端程序编写 (1).socket (2).bind (3).listen (4).accept,返回值是一个fd,accept正确返回就表示我们已经和前来连接我的客户端之间建立了一个TCP连 ...