背景知识:
从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();
}
}
|
在编译时,会提示以下错误信息:
OverrideTest.java:4:
方法未覆盖其父类的方法
@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
}
}
|
在编译时,会得到以下提示信息:
注意:DeprecatedDemo.java
使用或覆盖了已过时的 API。
注意:要了解详细信息,请使用 -Xlint:deprecation
重新编译。
|
如果在编译时添加-Xlint:deprecation参数,我们能更清楚的看到该警告的详细信息,如下:
DeprecatedDemo.java:6:
警告:[deprecation] SomeClass
中的 DeprecatedMethod()
已过时
SomeClass.DeprecatedMethod();
^1
警告
|
要注意@Deprecated与@deprecated的区别,@deprecated是为了生成文档的需要,例如:
class DeprecatedClass {
/**
* @deprecated此方法已过时,不建议使用
*/
@Deprecated
public static void DeprecatedMethod() {
// TODO
}
}
|
3、@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
参数
|
说明
|
deprecation
|
使用了过时的类或方法时的警告
|
unchecked
|
执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型
|
fallthrough
|
当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
|
path
|
在类路径、源文件路径等中有不存在的路径时的警告
|
serial
|
当在可序列化的类上缺少 serialVersionUID 定义时的警告
|
finally
|
任何 finally 子句不能正常完成时的警告
|
all
|
关于以上所有情况的警告
|
通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数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注释时,编译器就会有如下提示:
注意:SuppressWarningsDemo.java
使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -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<? extends RuntimeException>[] 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是一个枚举类型,它具有以下定义:
ElementType值
|
说明
|
ElementType.ANNOTATION_TYPE
|
应用于注释类型声明
|
ElementType.CONSTRUCTOR
|
构造方法声明
|
ElementType.FIELD
|
应用于字段声明(包括枚举常量)
|
ElementType.LOCAL_VARIABLE
|
应用于局部变量声明
|
ElementType.METHOD
|
应用于方法声明
|
ElementType.PACKAGE
|
应用于包声明
|
ElementType.PARAMETER
|
应用于参数声明
|
ElementType.TYPE
|
应用于类、接口(包括注释类型)或枚举声明
|
@Retention的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在
Retention 注释,则保留策略默认为
RetentionPolicy.CLASS,例如:
@ Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
...
}
|
java.lang.annotation.RetentionPolicy是一个枚举类型,它具有以下定义:
RetentionPolicy值
|
说明
|
RetentionPolicy.CLASS
|
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释
|
RetentionPolicy.RUNTIME
|
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取
|
RetentionPolicy.SOURCE
|
编译器要丢弃的注释
|
@Documented的用法:指示某一类型的注释将通过
javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented
来注释的,则其注释将成为注释元素的公共 API
的一部分。Documented是一个没有成员的注释。
@Inherited的用法:指示注释类型自动被子类继承。
Inherited也是一个没有成员的注释。
注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。
分享到:
相关推荐
### Annotation在Java 1.5中的入门介绍与应用 #### 背景知识与概念引入 自Java 5.0版本起,Sun Microsystems(现Oracle)引入了一项新特性——Annotation(注解),这一功能旨在简化开发过程中的元数据管理,并...
我们有必要对JDK 5.0新增的注解(Annotation)技术进行简单的学习,因为Spring 支持@AspectJ,而@AspectJ本身是基于JDK 5.0的注解技术。所以学习JDK 5.0的注解知识有助于我们更好地理解和掌握Spring的AOP技术。 ...
本文主要探讨了Java的基础知识以及在JDK 5.0中引入的一些新特性,旨在帮助开发者强化Java编程技能。 首先,Eclipse是Java开发中常用的集成开发环境(IDE),它提供了丰富的功能来支持开发过程。工作空间(workspace...
一个Maven插件,用于处理jdk8及更高版本的编译时注释。 该插件有助于从Maven使用JDK8提供的集成在Java编译器中的新注释处理 该插件是Maven apt插件的“ alter ego” 文献资料 相关插件 插入 信息 Jboss的eclipse...
Java Annotation,也称为注解,是Java编程语言中的一种元数据机制,自JDK 5.0开始引入。注解提供了在源代码中嵌入元数据的能力,这些元数据可以被编译器、构建工具或者运行时环境用来处理代码。它们在代码中看起来...
这里我们将深入探讨Eclipse IDE的使用,JDK 5.0引入的新特性,以及如何有效地利用它们进行更高效的编程。 Eclipse是一款强大的集成开发环境(IDE),广泛用于Java EE开发。它提供了诸如代码自动完成、错误检测、...
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节...
JDK 1.5,代号“Tiger”,也被称为Java 5.0,引入了一系列重大的语言和库改进,显著提升了开发效率和代码质量。本文将深入探讨这些新特性,分享实际应用中的经验和技巧。 首先,让我们从增强的for循环开始。这种新...
定义:注解(Annotation),也叫元数据。...它是JDK5.0及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
根据给定的文件信息,我们将介绍Java注解(Annotation)的相关知识点,包括其定义、使用方法、内建注解以及高级特性。 首先,我们来看看Java注解的由来。在Java 5.0版本发布之前,程序员通常需要使用注释(Comments...
在JDK 1.8.0_291的src/java/lang/annotation路径下,可以找到JDK注解包的源代码。注解是Java SE 5.0引入的一个特性,用于提供一种形式的元数据,可以被编译器检查或被工具或运行时用来生成代码、配置文件等。通过为...
JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。 内置的注解 作用在代码的注解是 @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,...
Java 注解(Annotation)是 JDK 5.0 及以后版本引入的一个特性,它是一个新的类型,与类、接口、枚举是在同一个层次。注解可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明、注释...
全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...
Java注解(Annotation)是自JDK 5.0版本起引入的一种元数据,它为程序提供了附加信息,但并不直接影响程序的运行。注解的主要目的是为了帮助编译器、构建工具、IDE或其他软件工具更好地理解和处理代码。注解与普通的...
在Java编程中,注解(Annotation)是一种强大的工具,自JDK 5.0引入以来,它极大地简化了代码管理和元数据的处理。注解不同于注释,它是代码的一部分,可以在编译、运行时被解析和执行特定的处理。本文将深入探讨...
在Java编程语言中,标注(Annotation)是一项重要的特性,自JDK 5.0引入以来,极大地丰富了Java的元数据处理能力。与传统的注释不同,标注不仅用于提供描述性信息,更重要的是它们能够被编译器或运行时环境所识别并...
Java注解,也称为Annotation,是自JDK 5.0版本起引入的一种元数据机制,它为程序提供了额外的信息,这些信息可以在编译时或运行时被解析和使用。元数据是描述数据的数据,注解就是一种特殊的数据类型,可以用于修饰...
Java注解在JDK 5.0版本被引入,它允许开发者为程序元素(如类、方法、变量等)添加注释信息,而这些信息将被编译器或者其他工具使用。注解通过使用@interface关键字来声明。元注解是用于注解注解的注解,常见的元...
Java 注解(Annotation)是 JDK 5.0 及以后版本引入的一个特性。它是一个新的类型,与接口类似,位于同一个层次,称为 Java 的一个类型(TYPE)。注解可以声明在包、类、字段、方法、局部变量、方法参数等的前面,...